decltype(auto)
(и, как правило, выводимый тип возврата) и конечный тип возврата являются ортогональными элементами.
Вы можете иметь:
decltype(auto) f() {}
auto f() -> decltype(auto) {}
Конечный тип возврата
Конечный тип возврата - это хорошо, особенно если иметь доступ к контексту, которого у нас нет до имени функции
как для шаблона:
template <typename T>
auto f(T x) -> decltype(bar(x));
против
template <typename T>
decltype(bar(std::declval<T&>())) f(T x);
или для зависимого имени в классе:
auto C::begin() -> iterator;
против
C::iterator C::begin();
Единственное место, где это требуется, - лямбда (если вы хотите / хотите явно указать тип возвращаемого значения):
[]() -> some_type {/*...*/}
[]() -> auto {/*...*/}
(что эквивалентно []() {/*...*/}
) []() -> decltype(auto) {/*...*/}
Случай, когда мы должны определить тип возврата лямбды, это когда он должен возвращатьсяссылочный тип.
выведенный тип возврата
Завершено с decltype(auto)
и auto
.
decltype(auto)
и auto
Тип удержания отличается, в основном как T&&
и T
.
Выведенный тип возврата требует определения тела.
Они также не допускают SFINAE, так как нет замены .