Вывод LValue Тип ссылки

Существует довольно много дискуссий и разъяснений относительно вывода аргументов шаблона и, в частности, свертывания ссылок и "универсальных ссылок". Этот вопрос проходит через соответствующие детали: как автоматически выводить тип? и эта статья Скотта Мейерса становится еще более подробной и, возможно, дает больше примеров и более широкий контекст: https://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers и его cppcon. слайды: http://www.aristeia.com/TalkNotes/C++TypeDeductionandWhyYouCareCppCon2014.pdf.
Мой вопрос касается следующего кода:

template <typename T> void f(T t) { t = 0; }

int main() {
  int i{5};
  int &ir{i};
  f(ir);
  cout << i << endl; // 5
  f<decltype(ir)>(ir);
  cout << i << endl; // 0
}

Почему мой шаблон работает f не выводят они типа int &? Согласно слайдам Скотта Мейерса (слайд 7) тот факт, что ir Ссылка lvalue просто игнорируется. Это прекрасно объясняет это поведение, но прекрасно объясняет, что я потратил некоторое время, читая справочник и стандарт, пытаясь найти, где написано что-то вроде:

Если A является ссылочным типом, указанный тип используется путем вычета.

Это то, что говорится в старой автономной версии справочника (которую я обычно использую), хотя это сказано в заголовке шаблона функции преобразования, и я не нашел эту формулировку в стандарте. Я обнаружил, что закрытие происходит из правил частичного упорядочения перегруженных шаблонов, но я не верю, что это применимо здесь, даже это было то, что я искал.


Есть ли где-то в стандарте, что это поведение указано, или это подразумевается другим поведением, которое я пропустил? Я действительно хотел бы быть в состоянии сказать кому-то ", который не выводит тип int & из-за этих слов в стандарте прямо здесь ".

1 ответ

Решение

В C++ нет выражений ссылочного типа. Тип переменной ir является int&, но тип выражения ir является int, Этот последний тип используется для вывода типа, поскольку аргументы функции всегда являются выражениями (за исключением особого случая фигурных скобок-init-списков).

Смотрите [expr.type]/1

Если выражение изначально имеет тип "ссылка на T"([Dcl.ref], [dcl.init.ref]), тип настраивается на T до дальнейшего анализа. Выражение обозначает объект или функцию, обозначенную ссылкой, и выражение является lvalue или xvalue, в зависимости от выражения.

Другие вопросы по тегам