Search code examples
c++c++11templatestemplate-argument-deduction

why c++ cannot infer templated nontype template argument?


Here is the code:

template <typename T, int P> struct _t_test_struct{
    T t;
    int p=P;
};
typedef _t_test_struct<float, 6> _test_struct6;

template <typename T, typename TP, TP P, template<typename, TP> class C>
void test1(C<T,P> &x){
    std::vector<T> _a;
    _a.resize(P);
    _a[0] = x.t;
    std::cout<<"typeid(P):"<<typeid(P).name()<<std::endl;

};

_test_struct6 _testp;
    _testp.t = 10;
    test1(_testp);

Why the compiler cannot determine the TP is int? I can only call it like test1<float, int>(_testp).


Solution

  • Why the compiler cannot determine the TP is int? I can only call it like test1<float, int>(_testp).

    Cannot if you compile C++11 or C++14.

    Can if you compile C++17, because C++17 improved template deduction rules.

    Suggestion: give a look at the corresponding page in CPP Reference.

    If I understand correctly, the problem is that until C++17 "Template type argument cannot be deduced from the type of a non-type template argument".

    In your case,

    template <typename T, typename TP, TP P, template<typename, TP> class C>
    void test1(C<T,P> &x)
    

    the TP type can't be deduced form P, a TP value (but works if you explicit TP, calling test1<float, int>(_testp))

    Starting from C++17, "When the value of the argument corresponding to a non-type template parameter P that is declared with a dependent type is deduced from an expression, the template parameters in the type of P are deduced from the type of the value.", so TP is deduced by P.