为什么C++17类模板参数推导失败?

为什么C++17类模板参数推导失败?,c++,templates,c++17,template-argument-deduction,class-template,C++,Templates,C++17,Template Argument Deduction,Class Template,C++17提供 我有一个小示例,您可以在启用C++17的情况下粘贴到onlinegdb中,在某些情况下失败是没有问题的,但我不知道为什么: #include <iostream> enum class Res{ ResA, ResB }; template<Res> class B{ }; template<Res T> class A{ //If I remove this construtor, template type

C++17提供

我有一个小示例,您可以在启用C++17的情况下粘贴到onlinegdb中,在某些情况下失败是没有问题的,但我不知道为什么:

#include <iostream>
enum class Res{
    ResA,
    ResB
};

template<Res>
class B{   
};

template<Res T>
class A{
    //If I remove this construtor, template type deduction will not work anymore
    public:   
    A(B<T> b){       
    }
};

template<>
class A<Res::ResA>{
    public:
    A(B<Res::ResA> b){
        std::cout<<"A res A\n";
    }  
};

int main()
{
    B<Res::ResA> b;
    A a(b);
}
上面的代码有效。但是,一旦我将A的构造函数更改为模板专门化中以外的任何其他构造函数,模板参数推断将不起作用,并且A必须由A初始化

我不知所措。为什么会这样?谢谢你的建议

仅从主模板生成


如果您不想在主模板中添加该构造函数,您仍然可以提供自定义演绎指南。

我猜编译器会忽略参数演绎的专门化。所以它不可能知道T应该是什么。FWIW,为了保持清醒,当你有一个模板专门化时,假装它不存在。直到主模板被解析,它们才真正发挥作用,并且只与主模板匹配模板专用化一起使用。在那之前,它只是那些特定模板参数的一个配方。Elliot,这在语义上有什么区别?谢谢NathanOliver的提示。同样感谢user253751。@Elliott在这种情况下没有任何扣减,模板参数只有一个默认值,因此它只能使代码适用于特定的专门化。这并不能真正回答问题,也不能解决CTAD的任何问题。它只会编译这个特定的代码片段。听起来棒极了!谢谢你的及时回复!