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
的隐式转换,我可以轻松地将A
B
传递给它。)

但模板化版本不编译:

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

该死的。。。标准化过程中没有任何内容;一个建议或是一些有帮助的东西?!无论如何,谢谢你把这件事弄清楚。