Deducing rvalue references in declarative contexts
Section [temp.deduct.type]
John Spicer

Created on 2009-04-16.00:00:00 last changed 96 months ago


Date: 2010-08-23.00:00:00

[Voted into WP at August, 2010 meeting.]

Date: 2010-02-15.00:00:00

Proposed resolution (February, 2010):

  1. Change [temp.deduct.type] paragraph 10 as follows:

  2. Similarly, if P has a form that contains (T), then each parameter type Pi of the respective parameter-type-list of P is compared with the corresponding parameter type Ai of the corresponding parameter-type-list of A. If P and A are function types that originated from deduction when taking the address of a function template ( [temp.deduct.funcaddr]) or when deducing template arguments from a function declaration ([temp.deduct.decl]) and Pi and Ai are parameters of the top-level parameter-type-list of P and A, respectively, Pi is adjusted if it is an rvalue reference to a cv-unqualified template parameter and Ai is an lvalue reference, in which case the type of Pi is changed to be the template parameter type (i.e., T&& is changed to simply T). [Note: As a result, when Pi is T&& and Ai is X&, the adjusted Pi will be T, causing T to be deduced as X&. —end note] [Example:

      template<typename T> void f(T&&);
      template<> void f(int&) { }      // #1
      template<> void f(int&&) { }     // #2
      void g(int i) {
        f(i);   // calls f<int&>(int&), i.e., #1
        f(0);   // calls f<int>(int&&), i.e., #2

    end example]

    If the parameter-declaration corresponding to Pi is a function parameter pack...

  3. Add a new section under 13.10.3 [temp.deduct], either before or after [temp.deduct.type], as follows:

  4. 14.8.2.x Deducing template arguments from a function declaration [temp.deduct.decl]

    In a declaration whose declarator-id refers to a specialization of a function template, template argument deduction is performed to identify the specialization to which the declaration refers. Specifically, this is done for explicit instantiations (13.9.3 [temp.explicit]), explicit specializations (13.9.4 [temp.expl.spec]), and certain friend declarations (13.7.5 [temp.friend]). This is also done to determine whether a function template specialization matches a placement operator new ( [basic.stc.dynamic.deallocation], [expr.new]). In all these cases, P is the type of the function template being considered as a potential match and A is the function type from the declaration. The deduction is done as described in [temp.deduct.type].

    If, for the set of function templates so considered, there is either no match or more than one match after partial ordering has been considered ( [temp.func.order]), deduction fails and the declaration is ill-formed.

(Note that the resolution of issue 674 depends on this resolution.)

Date: 2010-08-23.00:00:00 [temp.deduct.call] paragraph 3 gives the deduction of rvalue references special treatment in the context of a function call:

If P is of the form T&&, where T is a template parameter, and the argument is an lvalue, the type A& is used in place of A for type deduction.

A similar provision is needed, but is not present, in declarative contexts. For example:

    template<typename T> void f(T&&);
    template<> void f(int&) { }    // #1
    template<> void f(int&&) { }   // #2
    void g(int i) {
        f(i);    // calls f<int&>(int&), i.e., #1
        f(0);    // calls f<int>(int&&), i.e., #2

There need to be rules that deduce the template arguments for the specializations in the same way that the arguments are deduced in the calls.

Date User Action Args
2014-03-03 00:00:00adminsetstatus: fdis -> c++11
2011-04-10 00:00:00adminsetstatus: wp -> fdis
2010-11-29 00:00:00adminsetstatus: dr -> wp
2010-08-23 00:00:00adminsetmessages: + msg2935
2010-08-23 00:00:00adminsetmessages: + msg2934
2010-08-23 00:00:00adminsetstatus: ready -> dr
2010-03-29 00:00:00adminsetstatus: review -> ready
2010-02-16 00:00:00adminsetstatus: drafting -> review
2009-08-03 00:00:00adminsetstatus: open -> drafting
2009-04-16 00:00:00admincreate