Т & Amp; & Amp; в шаблонной функции и классе

Я только что наткнулся на это T&& в классе и функции означает разные вещи.
В функции:

template<class T> void f(T&& t){};   // t is R or L-value
...
int i=0;
f(i);   // t in f is lvalue
f(42);  // t in f is rvalue

В классе:

template<class T>
struct S {
S(T&& t){}  // t is only R-value?
};
...
int i;
S<int> ss(i);   // compile error - cannot bind lvalue to ‘int&&’

Означает ли это, что если у нас естьT&& t в классе, чем t будет только рвалуе?
Кто-нибудь может указать мне, где я могу получить больше информации об этом?
Означает ли это, что мне нужно написать две перегрузки метода для L и R-значений?

ОТВЕТ
Как показывает пример Альфа, t в функции и классе может быть Lvalue или Rvalue.

1

Решение

В вашей функции T выводится из фактического аргумента. Основное использование для этой конкретной комбинации идеальная пересылка. В шаблоне класса T не выводится, оно должно быть указано.

Например, это прекрасно компилируется как с g ++, так и с msvc:

template<class T>
struct S {
S(T&& t){}
};

int main()
{
int i;
S< int& > ss(i);
}
2

Другие решения

Вы имеете дело с выводом аргументов шаблона здесь.

Используя f без явно определяя аргумент шаблона, компиляторы C ++ теперь должны решить, какой тип аргумента шаблона T от параметров вы передаете его.

Правила вывода аргументов шаблона с && типы являются специальными, чтобы обеспечить идеальную пересылку. Когда вы используете f(i), T выводится как T&, Таким образом, параметр t имеет тип T& &&, который падает до T&, Тем не менее, когда вы используете f(42)тип T выводится как T&&, и поэтому t является T&& &&, который падает до T&&,

Однажды ты сила T чтобы быть конкретным типом, все, что эффективно уходит. Разрушение все еще может произойти, но потому что вы использовали S<int>, затем t будет иметь тип int&&, S<int> ss(i) фактически является эквивалентом f<int>(i), что тоже не законно. А так как вывод аргументов шаблона работает только с функциями, а не с типами, вы должны сделать что-то подобное для S если вы хотите совершенную пересылку:

template<class T>
struct S {
template<class U>
S(U&& t){}
};

Конечно, вы можете использовать методы SFINAE и метапрограммирование шаблона, чтобы гарантировать, что шаблон конструктора может быть создан только в том случае, если базовый тип T а также U подобные.

9

По вопросам рекламы [email protected]