Clang无法从auto返回值的operator==生成operator!=的模板实例化问题
Clang与GCC对运算符重写返回值推导的处理差异
问题代码与编译现象
以下代码在GCC中可正常编译,但在Clang中编译失败:
template <typename T> struct Wrapper { T value; constexpr auto operator==(const T other) const { return value == other; } }; template <Wrapper W> void fun() { static_assert(W != 0); // 该行在Clang上编译失败 } int main() { fun<Wrapper{1}>(); }
Clang的报错信息:
<source>:11:21: error: return type 'auto' of selected 'operator==' function for rewritten '!=' comparison is not 'bool' 11 | static_assert(W != 0); // This line fails on Clang | ~ ^ ~ <source>:15:5: note: in instantiation of function template specialization 'fun<Wrapper<int>{1}>' requested here 15 | fun<Wrapper{1}>(); | ^ <source>:4:20: note: declared here 4 | constexpr auto operator==(const T other) const { | ^
关键观察点
- 将
operator==的返回值从auto显式改为bool后,代码可在两款编译器上正常编译。 - 若在
static_assert前添加一行void(W == 0);,代码也能在两款编译器上通过:template <Wrapper W> void fun() { void(W == 0); // 添加该行可消除错误 static_assert(W != 0); } - 若将
Wrapper改为非模板类,代码同样可在两款编译器上成功编译。
结论
这是Clang/LLVM的bug。问题出在Clang处理运算符重写(!=由==重写而来)时,对auto返回值的推导逻辑与GCC不一致:
- 直接使用
W != 0时,Clang未能正确推导重写!=所用的operator==的实际返回类型为bool,尽管value == other的结果本质是bool。 - 提前显式调用
W == 0会触发operator==的返回值推导,后续重写!=时就能正确识别返回类型;非模板类的Wrapper不存在模板实例化时的推导延迟问题,因此也能正常编译。
内容的提问来源于stack exchange,提问作者nokz
相关产品推荐
相关产品推荐

