【发布时间】:2019-06-27 20:25:17
【问题描述】:
这段代码:
#include <iostream>
template <typename T>
void print_type(){ std::cout << __PRETTY_FUNCTION__ << '\n'; }
template <typename T>
struct foo {
operator T(){
std::cout << "T conversion ";
print_type<T>();
return {};
}
template <typename S>
operator S(){
std::cout << "ANY conversion ";
print_type<S>();
return {};
}
};
int main(void) {
unsigned a = 20;
foo<uint8_t> z;
auto y = z*a;
}
compiles (with gcc 9.1.0) and prints:
ANY conversion void print_type() [with T = int]
另一方面,如果我删除operator T(上面没有调用):
template <typename T>
struct bar {
template <typename S>
operator S(){
std::cout << "ANY conversion ";
print_type<S>();
return {};
}
};
int main(void) {
unsigned a = 20;
bar<uint8_t> z;
auto y = z*a;
}
我收到一个错误:
prog.cc: In function 'int main()':
prog.cc:19:15: error: no match for 'operator*' (operand types are 'bar<unsigned char>' and 'unsigned int')
19 | auto y = z*a;
| ~^~
| | |
| | unsigned int
| bar<unsigned char>
起初我很惊讶foo 需要operator T 才能选择operator S。但是,gcc 就在这里吗? Clang 8.0 complains with
prog.cc:24:15: error: use of overloaded operator '*' is ambiguous (with operand types 'foo<uint8_t>' (aka 'foo<unsigned char>') and 'unsigned int')
auto y = z*a;
~^~
prog.cc:24:15: note: built-in candidate operator*(float, unsigned int)
prog.cc:24:15: note: built-in candidate operator*(double, unsigned int)
prog.cc:24:15: note: built-in candidate operator*(long double, unsigned int)
prog.cc:24:15: note: built-in candidate operator*(__float128, unsigned int)
[...]
...列表继续列出各种候选人。
为什么第一个例子用 gcc 编译而不用 clang?这是 gcc 中的错误吗?
【问题讨论】:
-
对我来说看起来像一个 gcc 错误。在这种情况下,我不确定您的转换运算符如何不会产生模棱两可的调用。
-
@NathanOliver 是的,我后来在没有真正考虑的情况下编辑了 clang 部分。我会改变这个问题,因为同时我确信
foo不应该编译
标签: c++ templates gcc operator-overloading language-lawyer