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

Should conversion operators be considered for function template argument deduction?

考虑以下 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<T&> 匹配的 S<int&>,并接受调用。

clang 不考虑转换运算符,无法将 T&int&& 匹配,并拒绝调用。

那么这里的语言是怎么说的呢?

GCC 在这里肯定是错误的:T&T&& 是 [temp.deduct.type]/8 中的不同行,因此不兼容。为什么这样做尚不清楚。在另一个方向上犯错误会更有意义:如果参数被声明为 S<T&&> 并且参数是 S<int&> 类型,那么至少会有一个 T (, int&) 这样(由于引用折叠)参数和参数类型相同。 (如果说涉及通用引用,也很容易犯错误。)