Home > Software engineering >  Why does template ordering matter when defining a method?
Why does template ordering matter when defining a method?

Time:07-10

I have the following code:

template<int n> 
struct array_container{double arr[n];};

template<int n>
struct avg{
    double first[n], second[n];

   template <int q>
   array_container<q> get_avg(double p) const;
};

I can add a definition for get_avg like this:

template<int n>
template<int q>
array_container<q>  avg<n>::get_avg(double p) const{
    array_container<q>   result;
    const int m = min(n,q);
    for(int k=0;k<m;k  ){result.arr[k] = p*first[k]   (1-p) * second[k];}
    return result;
}

If I were to replace the first two lines of the definition, namely:

template<int n>
template<int q>

with any one of these:

template<int q>
template<int n>
template<int n, int q>
template<int q, int n>

compilation would fail . Why is this so? I see no significance in the order of the templates when defining for array_container<q> avg<n>::get_avg(double p) const .

Edit: I understand that in the current standard the ordering of the template parameter clauses in the definition must correspond exactly to that of the declaration. My question is relating to the design of the language.

Is there any reason, relating to logic or consistency, why my alternative examples could not be considered equally as valid? Especially since the compiler can already deduce the correct candidate if I provide it with an "incorrect" ordering.

CodePudding user response:

Why is this so?

Because when providing an out-of-class definition the first parameter clause template<int n> corresponds to the outermost enclosing class template while the second parameter clause template<int q> corresponds to the member template get_avg itself. More importanty when providing an out-of-class definition for the member template, the outermost parameter clause(for the class template(if any)) must come first, then the clause for the member templates(if any) .

template<int n>  //parameter clause corresponding to the outermost class template
template<int q>  //parameter claluse corresponding to the the member template itself
array_container<q>  avg<n>::get_avg(double p) const{
    array_container<q>   result;
    const int m = min(n,q);
    for(int k=0;k<m;k  ){result.arr[k] = p*first[k]   (1-p) * second[k];}
    return result;
}
  • Related