В чем разница между const T & и T & в вычитании шаблона - PullRequest
3 голосов
/ 18 марта 2019
#for example:

#1:
template <typename T>
void func(T &) {}
int a;
const int b;
func(a);           // T ->  int
func(b);           // T ->  const int
func(5);           // wrong. 5 is a right value

#2:
template <typename T>
void func(const T &) {}
int a;
const int b;
func(a);     // T ->  int
func(b);     // T ->  int   
func(5);     // T ->  int

#3
template <typename T>
void func(T &&) {}
func(5);     // T ->  int

Мой вопрос:

почему не работает 1-й код, почему это связано со значением влево / вправо;

почему T в 3'не является const int

Ответы [ 2 ]

1 голос
/ 18 марта 2019

почему первый код не работает; почему это связано с левым / правым значением;

Для 1-го случая T будет выведено как int, тогда тип параметра будет int &, который является lvalue-ссылкой на неконстантный. И 5 является значением rvalue, которое не может быть привязано к lvalue-ссылке на неконстантное значение, и тогда вызов не удался.

Для второго случая тип параметра функции - const int &, т. Е. Lvalue-ссылка на const, которая может связываться с rvalue, как 5.

почему T в 3-м не const int

Вывод аргумента шаблона не будет добавлять const, если аргумент не относится к типу const. 5 имеет тип int (и это r-значение), но его тип не const int.

С другой стороны, у нас есть ссылка для переадресации для работы с lvalues ​​/ rvalues. например, * * одна тысяча тридцать две

template <typename T>
void func(T &&) {}
int a;
const int b;
func(a);           // T ->  int&;       parameter type -> int&
func(b);           // T ->  const int&; parameter type -> const int&
func(5);           // Fine. T ->  int;  paramter type -> int&&
0 голосов
/ 18 марта 2019

Все сводится к свойствам выражений. 5 это выражение. У него есть тип и категория значения. Тип 5 - int, не const int, а просто int. И это prvalue (это категория значения).

Таким образом, при выводе T& против 5 тип может быть выведен только как int. Это означает, что синтезированная функция принимает int&, которая не может связываться с r-значением.

При выводе T const& тип T все еще может быть выведен только как int согласно соответствующим положениям в вычете аргумента шаблона. Но теперь синтезированная функция принимает int const&, и это может очень хорошо связываться с r-значением.

...