Why can't C++ deduce T in a call to Foo<T>::Foo(T&&)?

jtbandes :

Given the following template struct:

template<typename T>
struct Foo {
    Foo(T&&) {}
};

This compiles, and T is deduced to be int:

auto f = Foo(2);

But this doesn't compile: https://godbolt.org/z/hAA9TE

int x = 2;
auto f = Foo(x);

/*
<source>:12:15: error: no viable constructor or deduction guide for deduction of template arguments of 'Foo'
    auto f = Foo(x);
             ^

<source>:7:5: note: candidate function [with T = int] not viable: no known conversion from 'int' to 'int &&' for 1st argument
    Foo(T&&) {}
    ^
*/

However, Foo<int&>(x) is accepted.

But when I add a seemingly redundant user-defined deduction guide, it works:

template<typename T>
Foo(T&&) -> Foo<T>;

Why can't T be deduced as int& without a user-defined deduction guide?

walnut :

I think the confusion here arises because there is a specific exception for the synthesized deduction guides regarding forwarding references.

It is true that the candidate function for the purpose of class template argument deduction generated from the constructor and the one generated from the user-defined deduction guide look exactly the same, i.e.:

template<typename T>
auto f(T&&) -> Foo<T>;

but for the one generated from the constructor, T&& is a simple rvalue reference, while it is a forwarding reference in the user-defined case. This is specified by [temp.deduct.call]/3 of the C++17 standard (draft N4659, emphasize mine):

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])).

Therefore the candidate synthesized from the class constructor will not deduce T as if from a forwarding reference (which could deduce T to be a lvalue reference, so that T&& is also a lvalue reference), but instead will only deduce T as non-reference, so that T&& is always an rvalue reference.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=29539&siteId=1