C++ 类模板的用户定义转换运算符被忽略(非模板的情况并非如此)
这段代码是编译的(重要的一点是C++ 类模板的用户定义转换运算符被忽略(非模板的情况并非如此),c++,c++11,templates,implicit-conversion,template-argument-deduction,C++,C++11,Templates,Implicit Conversion,Template Argument Deduction,这段代码是编译的(重要的一点是F()只接受As,并且由于存在从B到A的隐式转换,我可以轻松地将AB传递给它。) 但模板化版本不编译: template <typename T> struct A {}; template <typename T> struct B { constexpr operator A<T> () const {return {};} }; template <typename T> void F (A<T
F()
只接受A
s,并且由于存在从B
到A
的隐式转换,我可以轻松地将AB
传递给它。)
但模板化版本不编译:
template <typename T>
struct A {};
template <typename T>
struct B {
constexpr operator A<T> () const {return {};}
};
template <typename T>
void F (A<T> a) {}
int main() {
F(B<int>());
return 0;
}
模板
结构A{};
模板
结构B{
constexpr运算符A()const{return{};}
};
模板
无效F(A){}
int main(){
F(B());
返回0;
}
GCC上有以下错误(MSVC上有同等错误):
错误:对“F(B)”的调用没有匹配的函数
(附加信息为存在F(A)
但B
不继承自A
)
作为记录,在A
中实现隐式转换运算符也没有帮助
为什么模板版本不能编译?我错过什么了吗?或者,实际上没有办法用类模板来实现它
(注释:我知道我可以明确地将<代码> b/COD>转换到<代码> A/COD>在调用站点;这不是我喜欢的。)
不考虑隐式转换。
类型推导不考虑隐式转换(除了上面列出的类型调整):这是超载分辨率的工作,稍后会发生。
必须首先推导模板参数T
(在重载解析之前),但如果参数A
带有参数B
,则无法从中推导出T
;然后编译失败
作为解决方法,您可以如前所述使用显式转换,或者显式指定模板参数
F<int>(B<int>());
F(B());
正如宋元耀更好地解释的那样,模板参数T
必须先推导出来
您可以解决解释T
类型的问题
F<int>(B<int>());
G(B<int>{});
因此,您可以调用F()
,通过G()
,而无需解释T
类型
F<int>(B<int>());
G(B<int>{});
G(B{});
该死的。。。标准化过程中没有任何内容;一个建议或是一些有帮助的东西?!无论如何,谢谢你把这件事弄清楚。