问题描述
请考虑以下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&
),使得(由于引用折叠)参数和参数类型相同。 (如果说涉及通用引用,也容易犯错误。)