auto,decltype(auto)和尾随返回类型

Vin*_*ent 3 c++ decltype auto trailing-return-type c++14

是否有区别:

template <class T>
constexpr decltype(auto) f(T&& x) -> decltype(std::get<0>(std::forward<T>(x)))
{
    return std::get<0>(std::forward<T>(x));
}
Run Code Online (Sandbox Code Playgroud)

和:

template <class T>
constexpr auto f(T&& x) -> decltype(std::get<0>(std::forward<T>(x)))
{
    return std::get<0>(std::forward<T>(x));
}
Run Code Online (Sandbox Code Playgroud)

如果是的话,它是什么,我应该使用哪一个来完美转发?

ken*_*ytm 6

尾随返回类型只能与.一起使用 auto

decltype(auto)vs 的要点auto区分返回类型应该是引用还是值的情况.但在您的情况下,返回类型已经明确定义为decltype(std::get<0>(std::forward<T>(x))),因此即使您使用它也将被完美转发auto.

auto f() -> T,"auto"关键字只是一个语法结构来填充类型位置.它没有其他目的.


实际上,在C++ 17中,你不能同时使用decltype(auto)带尾随返回类型的.

C++ 14措辞(n3936§7.1.6.4[dcl.spec.auto]/1):

autodecltype(auto) 类型说明符指定将以后,无论是通过从一个初始化扣除或通过用明确的规范被替换的占位符类型尾返回型.该auto 类型说明符还用于表示的λ是一个通用的λ.

C++ 17措辞(n4618§7.1.7.4[dcl.spec.auto]/1):

autodecltype(auto) 类型说明符用于指定将在后面通过扣除从一个初始化替换的占位符类型.该auto 类型说明符还用于引入具有一个功能类型尾返回型或以表示的λ是一个通用的拉姆达(5.1.5).该auto 类型说明符还用来引入分解声明(8.5).

这是DR 1852,请参阅trailing-return-type中的占位符是否覆盖初始占位符?.

实际上,虽然gcc接受decltype(auto) f() -> T(这是一个错误),但clang拒绝它说

error: function with trailing return type must specify return type 'auto',
not 'decltype(auto)'
Run Code Online (Sandbox Code Playgroud)