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;
}