考虑以下code:
template<typename>
struct S
{
operator S<int&>();
};
template<typename T>
void f(S<T&>);
int main()
{
f(S<int&&>{}); // gcc ok
// clang error
}
gcc在临时参数上使用转换运算符,返回与S<int&>
匹配的S<T&>
并接受调用。clang不考虑转换运算符,无法将
T&
与int&&
匹配,并拒绝该调用。那么该语言说的应该在这里发生什么呢?
最佳答案
GCC在这里肯定是错误的:T&
和T&&
是[temp.deduct.type]/8中的不同行,因此不兼容。为什么这样做尚不清楚。在另一个方向上犯错会更有意义:如果将参数声明为S<T&&>
,而参数的类型为S<int&>
,则至少会有一个T
(即int&
),使得(由于引用折叠)参数和参数类型相同。 (如果说涉及通用引用,也很容易犯一个错误。)