简体   繁体   中英

Role of default template parameters in overload resolution of (partially specialized) class templates

This answer explains the behaviour of the following program:

template<typename A, typename B = int >
struct FirstWins {
    static constexpr int i = 1;
};
template<typename A>
struct FirstWins<A, float/* anything different from int */ > {
    static constexpr int i = 2;
};

template<typename A, typename B = int >
struct SecondWins {
    static constexpr int i = 1;
};
template<typename A>
struct SecondWins<A, int > {
    static constexpr int i = 2;
};

int main()
{
    typedef void Whatever_t;
    cout << FirstWins < Whatever_t >::i << endl;  // prints 1
    cout << SecondWins< Whatever_t >::i << endl;  // prints 2
    return 0;
}

However, I cannot find an actual reference describing explicitly this behaviour and thus confirming the answer.

I could not find on cppreference.com a sentence confirming that explicit template arguments are preferred over default ones.

I suspect that this is not really the rule. The rule is that whenever there is a partial template specialization matching the template arguments, that specialization is always chosen over the instantiation of the primary template. Is this correct? (in this case, the docs somehow explain this rule, but again not explicitly).

template<typename A, typename B = int >
struct S {
//...
};

Can be seen as

template<typename A, typename B = int >
struct S;
// So S<A> is S<A, int>

// Primary template
template<typename A, typename B>
struct S
{
   //...
};

// Possible specialization as
template<typename A>
struct S<A, int>
{
   //...
};

then, it is more clear which instantiation to use.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM