C++ 具有模板化函数参数的隐式类型转换

C++ 具有模板化函数参数的隐式类型转换,c++,templates,c++17,implicit-conversion,C++,Templates,C++17,Implicit Conversion,如果我有一个简单的函数,它的类型如下: class X { public: X( int ){} }; void fx( X ) {} fx( 1 ); // implicit converted to X(int); // fine! 如果我对模板类型尝试同样的方法,它将不起作用 template <typename T> class Y { public: Y( T ){}; }; template <typen

如果我有一个简单的函数,它的类型如下:

class X
{
    public:
        X( int ){}
};

void fx( X  ) {}



fx( 1 ); // implicit converted to X(int); // fine!
如果我对模板类型尝试同样的方法,它将不起作用

template <typename T>
class Y
{
    public:
        Y( T ){};
};

template <typename T>
void fy( Y<T> );

fy( 2 ); // Y<int> expected, but it fails
模板
Y类
{
公众:
Y(T){};
};
模板
无效fy(Y);
财政年度(2);//我没料到,但失败了
有什么把戏可以强迫你转换吗


要做到这一点,需要隐式的,直接访问fy不是我们想要的。我知道我可以通过指定模板参数强制所有模板;)

模板参数推导不考虑任何隐式转换

您可以手动指定所需的实例化:

fy<int>(2);
使用C++17之前的版本

fy(Y<int>(2));
fy(Y(2));

中不考虑隐式转换;模板参数
T
就是无法推导

类型推导不考虑隐式转换(除了上面列出的类型调整):这是超载分辨率的工作,稍后会发生。

您可以编写一个助手函数模板

template <typename T>
void helper(T&& t) {
    fy<std::decay_t<T>>(std::forward<T>(t)); // specify the template argument explicitly
}

参数中不能包含隐式转换和模板推断。另一种打破它的方法:

template <typename T>
void fy( T x ) {
    Y<T> y = x;
    //Use y
    return;
}
模板
无效fy(T x){
Y=x;
//使用y
返回;
}

当然,根据
fy
的不同,您可以将
x
直接用作
T
,并在函数中动态隐式转换。

@Ron:很抱歉不够精确:对我来说,隐式转换很重要。手动定义模板参数在我的用例中没有帮助。
Y
Y
Y
将是可行的。您希望编译器如何决定?很抱歉不够精确:对我来说,隐式处理非常重要。手动定义模板parms在我的用例中没有帮助。好的,所以答案很简单:否!:-)因为我想写一个需要隐式转换的助手,所以写一个显式转换的助手与我的基本想法相反。我的想法只是基于“隐式”转换,所以这根本不是一种可能的方式。谢谢@宋元耀:你可能想要
std::detacy_t
来处理(const)引用。如果你已经有
fy(Y)
的代码,你可以把
template void fy(tx){fy(Y(x));}
作为重载包装器。
helper(2); // T will be deduced as int
template <typename T>
void fy( T x ) {
    Y<T> y = x;
    //Use y
    return;
}