Deducing template arguments during partial ordering when parameters are function parameter pack

前端 未结 1 1508
别跟我提以往
别跟我提以往 2021-01-03 06:22

N4527 14.8.2.4 [temp.deduct.partial]

3 The types used to determine the ordering depend on the context in which the partial ordering is done:

相关标签:
1条回答
  • 2021-01-03 06:36

    Why f(1, 2, 3); calls #2?

    There's a lot of questions in your question (one question per question please!), so I will stick to that one. First, we perform template deduction. #3 fails, but #1 and #2 succeed:

    template<class... Args>
    void f(Args... args);        // #1, with Args = {int, int, int}
    template<class T1, class... Args> 
    void f(T1 a1, Args... args); // #2, with T1 = int, Args = {int, int}
    

    Both functions take three ints by value, so all the normal tiebreakers in overload resolution fail to resolve the ambiguity. So we get to the very last one:

    Given these definitions, a viable function F1 is defined to be a better function than another viable function F2 if for all arguments i, ICSi(F1) is not a worse conversion sequence than ICSi(F2), and then
    — [...]
    F1 and F2 are function template specializations, and the function template for F1 is more specialized than the template for F2 according to the partial ordering rules described in 14.5.6.2.

    The rules are:

    Step 1: synthesize types [temp.func.order]:

    To produce the transformed template, for each type, non-type, or template template parameter (including template parameter packs (14.5.3) thereof) synthesize a unique type, value, or class template respectively and substitute it for each occurrence of that parameter in the function type of the template.

    So we have:

    void f(Pack1... args);         // #1
    void f(U2 a1, Pack2... args);  // #2
    

    Step 2: perform deduction as described in [temp.deduct.partial]. The context we're in is a function call, so we use the types for which the function call has arguments.

    First, we try to deduce #2 from #1. That is, we try to match (T1, Args...) against (Pack1...). The first part is then P = T1, A = Pack1.... We have:

    If A was transformed from a function parameter pack and P is not a parameter pack, type deduction fails.

    So deducing #2 from #1 fails, so the argument Args... is not at least as specialized as T1, Args....

    Next, we try to deduce #1 from #2. That is, we try to match (Args...) against (U2, Pack2...). That succeeds, so T1, Args... is at least as specialized as Args....

    Since #2 is at least as specialized as #1 and #1 is not at least as specialized as #2, we can say that #2 is more specialized:

    Function template F is at least as specialized as function template G if, for each pair of types used to determine the ordering, the type from F is at least as specialized as the type from G. F is more specialized than G if F is at least as specialized as G and G is not at least as specialized as F.

    The more specialized template is preferred, so we call #2.

    0 讨论(0)
提交回复
热议问题