Search code examples
c++c++17partial-specializationctad

Partial deduction of template parameter using constructor


I have seen this asked before in several ways, and all the solutions are always the same: use a helper function or even use nested classes. For me, both of those solutions look clumpsy. So I wonder how come in the c++17/c++20 era there is not better solution to this problem:

EDIT: The question here is if there is any method to use impl<int> i(b);, because currently compiler fails due to the lack of second template argument.

template<class T1, class T2>
struct impl
{
    impl(const T2& _t2) : t2(_t2) {}

    T1 t1;
    const T2& t2;
};

int main()
{
    int a{};
    double b{};
    impl<int, double> i(b);//This works...
    impl<int> i(b);//... but this doesn't due to lack of 2nd template parameter!!!
}

I understand that partial spetialization can present problems in some cases, but it is not possible to use CTAD or any other method in this case??? If so, how?


Solution

  • I most often use a "type tag" to overcome this kind of problems. It also comes in handy for similar issues, like the lack of partial specialization of function templates.

    #include <type_traits>
    
    template<typename T> struct type_t{};
    template<typename T> constexpr type_t<T> type;
    
    template<class T1, class T2>
    struct impl
    {
        impl(const T2& _t2, type_t<T1> = {}) : t2(_t2) {}
    
        T1 t1;
        const T2& t2;
    };
    
    int main()
    {
        int a{};
        double b{};
        impl<int, double> i(b);//This works...
        impl j(b, type<int>); // This works as well
        static_assert(std::is_same_v<decltype(j),impl<int, double>>);
    }