是否应考虑将转换运算符用于函数模板参数推导?

问题描述

请考虑以下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&>,则至少会有一个Tint&),使得(由于引用折叠)参数和参数类型相同。 (如果说涉及通用引用,也容易犯错误。)