c++ - 不同版本的g++重载解析结果不一致
问题描述
当我使用 g++ 5.4.0 时,下面的示例代码按预期工作,但在我将 g++ 更新到 10.2.0 后,结果发生了变化。我还在clang++ 11.0.1上测试了示例代码,结果和g++ 5.4.0一样。
我搜索了一些相关问题,但没有得到有效的答案。据我所知,重载函数应该在模板之前匹配,为什么g++ 10.2.0会得到不同的结果,我该如何解决这个问题?
因为原来的源代码很复杂,用其他的c++特性来重构并不容易,这个问题能不能稍微改动一下就解决?
示例代码的目标是使用重载函数Base::operator const std::string&()
执行一些特殊动作,使用模板函数执行常见动作。
#include <string>
#include <iostream>
class Base
{
public:
template <class T>
operator const T&() const;
virtual operator const std::string&() const;
};
template <class T>
Base::operator const T&() const
{
std::cout << "use template method" << std::endl;
static T tmp{};
return tmp;
}
Base::operator const std::string&() const
{
std::cout << "use overload method" << std::endl;
const static std::string tmp;
return tmp;
}
template <class T>
class Derive : public Base
{
public:
operator const T&() const
{
const T& res = Base::operator const T&();
return res;
}
};
int main()
{
Derive<std::string> a;
const std::string& b = a;
return 1;
}
g++ 5.4.0 结果:
g++ -std=c++11 main.cpp -o test && ./test
use overload method
g++ 10.2.0 结果:
g++ -std=c++11 main.cpp -o test && ./test
use template method
clang++ 11.0.1 结果:
clang++ -std=c++11 main.cpp -o test && ./test
use overload method
解决方案
这绝对是一个 GCC 错误:
template <class T>
class Derive : public Base {
public:
operator const T&() const override {
using Y = std::string;
static_assert(std::is_same<T, Y>::value, "");
std::string static res;
res = Base::operator const Y&();
res = Base::operator const T&();
return res;
}
};
在这里,虽然调用了两个不同版本的运算符,但Y
它们T
是相同的。Godbolt
Clang 具有正确的行为,您可以将其用作解决方法。请报告该错误,以便可以在 GCC 的后续版本中修复它。
推荐阅读
- java - 翻转log4j时如何在旧日志文件名中使用文件创建日期
- vim - vim/gvim 格式 (%!column -t) 不起作用,而是过滤所有行
- typescript - 创建映射类型时引用索引类型?
- python - 在 python 中从 MediaCloud 中检索文本文章的正文
- opencv - Cuda opencv 需要更多时间
- scala - java.io.FileNotFoundException:文件不存在:hdfs://data.xxxxx.avro
- reactjs - 在 ReactJs 中动态地将值放入表中
- php - 使购物车页面上的 Woocommerce 商店消息在 6 秒后消失
- masstransit - 当消费者处于重试状态时停止总线以某种方式使消息移动到_skipped队列
- scala - 如何管理 application.config 文件以最小化播放框架中的代码