Can the implicit template subtraction guideline infer a reference type?

While testing the behavior of the C ++ 17 deduction guide with gcc7, I found that this example fails:

template<class T>
struct S{
  S(T&& v){}
};
int i=10;
auto v = S(i);

      

According to what I read from the cpp reference , I thought I v

should have a type S<int &>

. However, gcc7 does not compile this code, complaining that int&

it cannot be linked to int &&

(the universal link mechanism does not work).

So my questions are:

  • If gcc7 deduced v

    as a type S<int&>

    ?

  • Where is the manual for automatic deduction in the project working standard described?

+3


source to share


1 answer


Rule in [over.match.class.deduct] :

A set of functions and function templates has been created, containing:
- For each constructor of a primary class template assigned by the template name, if a template is defined, a function template with the following properties:
    - template parameters are class template parameters followed by template parameters (including template arguments by default) constructor, if any.
    - Function parameter types are constructor parameters.
    - The return type is a specialization of the class template, denoted by template-name and template arguments corresponding to the template parameters obtained from the class template.

Our kit includes:

template <class T> // <-- the template parameters come from the class template
S<T>               // <-- the return type is the class template specialization   
foo(T&& );         // <-- the types of the parameters are those of the constructor

      

We do overload resolution as usual, which involves pattern subtraction. But from [temp.deduct.call] :



A forwarder reference is an rvalue reference to the cv-unqualified template parameter , which is not a class template template (when outputting a template template argument ([over.match.class.deduct])). If P is a forwarding reference and the argument is an lvalue, type "lvalue reference to A" is used for type inference instead of "A".

Hence, this one T&&

is not a forwarding link. This is the rvalue for T

. So deduction against lvalues ​​(in our case S(i)

) fails. gcc correctly rejects your code here.

If you want a class template parameter to function as a forwarding reference, you will need to add a deduction guide:

template <class T> S(T&& ) -> S<T>;

      

+6


source







All Articles