#опытным
decltype(auto) и auto&& позволяют нам не беспокоиться о конкретных типах сущностей, включая ref квалификацию. Основные кейсы применения decltype(auto) - это автоматический вывод типа возвращаемого значения функции и переменной на основе инициализатора. Но чем отличаются decltype(auto) и auto&& в контексте этих кейсов? Спасибо @SoulslikeEnjoyer за идею для постов в этом комменте https://t.me/c/2009887601/47858.
Так как вывод типов можно применять в разных ситуациях, то разобьем тему на части и сегодня мы поговорим конкретно про это автоматический вывод типа переменной на основе инициализатора.
Чтобы продемонстрировать различия нам нужна вот такая заготовка:
int g = 0;
int foo() {return 42;}
int& foo1() {return g;}
int&& foo2() {int i = 42; return std::move(i);}
auto&& a1 = foo();
auto&& a2 = foo1();
auto&& a3 = foo2();
decltype(auto) b1 = foo();
decltype(auto) b2 = foo1();
decltype(auto) b3 = foo2();
Здесь касательно вывода типа нас интересует, как ссылочность типа возвращаемого значения функции (или ее отсутствие), сказывается на типе переменных.
Чтобы заглянуть под капот этого дела, я буду использовать полезнейший инструмент - cppinsights. Эта тулза позволяет снимать слои магии и показывает суть. И вот, что она показала:
int && a1 = foo();
int & a2 = foo1();
int && a3 = foo2();
int b1 = foo();
int & b2 = foo1();
int && b3 = foo2();
Здесь можно четко увидеть разницу: при возврате из функции не-ref-квалифицированного типа, decltype(auto) в точности передает тип, а вот auto&& определяет тип как правую ссылку.
Проблема ли это?
a1 по идее должна быть висячей ссылкой, так как объект тут же разрушится. Но на самом деле в этом случае правая ссылка продлевает время жизни объекта, возвращенного из функции, до конца времени жизни ссылки.
Поэтому в большинстве кейсов при объявлении переменной использование decltype(auto) избыточно, auto&& прекрасно справляется.
Единственное, когда его нужно использовать - в тестах всякого шаблонного непотребства, чтобы получить точный тип возвращаемого значения и сравнить его с образцом.
В следующий раз обсудим, какие различия между ними при использовании автоматического вывода типа возвращаемого значения функции.
Be laconic. Stay cool.
#cppcore #cpp14