【发布时间】:2014-12-21 09:09:47
【问题描述】:
以下最小代码可以在 g++ 上编译,但不会在 clang++ 上编译:
template<class T>
T operator*(float a, const T& b)
{
return b * a;
}
struct A{
A operator*(float b) const
{
A a;
return a;
}
};
int main()
{
A a;
2.0f * a;
}
这是我得到的错误:
$ clang++ test.cpp
test.cpp:2:3: error: overloaded 'operator*' must have at least one parameter of
class or enumeration type
T operator*(float a, const T& b)
^
test.cpp:4:11: note: in instantiation of function template specialization
'operator*<float>' requested here
return b * a;
^
test.cpp:18:10: note: in instantiation of function template specialization
'operator*<A>' requested here
2.0f * a;
^
1 error generated.
Clang 版本 3.5。此代码有效吗? Clang 有 bug 吗?
【问题讨论】:
-
我认为@Namfuak 发现了一个重复:表达式
b * a尝试实例化运算符函数模板,这导致T被推断为float,并且产生的特化(运算符function) 是格式错误的,因为它没有类/枚举类型的参数或其引用。这似乎不是替换失败,即硬错误。参见 [over.oper]/1 和 /6。 -
我试图进一步最小化您的代码并删除了
A::operator*... 但注意到这会阻止 GCC 编译代码。有趣... -
@LightnessRacesinOrbit 错误消息很有趣:它暗示替换,这不应该是问题。没有从
A到float的有效转换是重载解决问题(在模板实例化后选择可行的重载)。
标签: c++ templates g++ clang clang++