Вывод 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, в зависимости от выражения.