Could an implicit template deduction guide deduce a reference type?

孤者浪人 提交于 2019-12-10 17:18:14

问题


While testing C++17 deduction guide behaviour 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 have read from cpp reference, I thought v should be of type S<int &>. Nevertheless gcc7 does not compile this code complaining that a int& can not be bound to a int && (the universal reference mechanism fails).

So my questions are:

  1. Should gcc7 have deduced v to be of type S<int&>?

  2. Where are described automatic deduction guide in the working draft standard?


回答1:


The rule in [over.match.class.deduct] is:

A set of functions and function templates is formed comprising:
- For each constructor of the primary class template designated by the template-name, if the template is defined, a function template with the following properties:
    - The template parameters are the template parameters of the class template followed by the template parameters (including default template arguments) of the constructor, if any.
    - The types of the function parameters are those of the constructor.
    - The return type is the class template specialization designated by the template-name and template arguments corresponding to the template parameters obtained from the class template.

Our set 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 perform overload resolution as usual, which involves template deduction. But from [temp.deduct.call]:

A forwarding reference is an rvalue reference to a cv-unqualified template parameter that does not represent a template parameter of a class template (during class template argument deduction ([over.match.class.deduct])). If P is a forwarding reference and the argument is an lvalue, the type “lvalue reference to A” is used in place of A for type deduction.

Hence, this T&& is not a forwarding reference. It is an rvalue reference to T. So deduction against an lvalue (in our case, S(i)) fails. gcc is correct to reject your code here.

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

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


来源:https://stackoverflow.com/questions/43521137/could-an-implicit-template-deduction-guide-deduce-a-reference-type

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!