Why C++17 class template argument deduction fails?

C++17 offers class template argument deduction.

I have the following small example (you can paste into onlinegdb with C++17 enabled, no problem) where it fails under certain circumstances but I do not know why:

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

The code above works. But as soon as I change A's constructor to be the any other constructor than in the template specializations, the template argument deduction will not work and A has to be initialized by A<Res::ResA>.

I am at loss. Why could this be the case? Thank you for any ideas!

1 answer

  • answered 2020-09-24 15:18 Jarod42

    Generated CTAD are only from primary template.

    If you don't want to add that constructor in primary template, you can still provide custom deduction guide.