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

时间:2017-03-12 05:51:02

标签: c++ c++14 auto decltype trailing-return-type

之间是否存在差异:

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));
}

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

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

1 个答案:

答案 0 :(得分:6)

尾随返回类型只能与auto

一起使用

decltype(auto) vs auto的重点是distinguish the case whether the return type should be a reference or value。但在您的情况下,返回类型已经明确定义为decltype(std::get<0>(std::forward<T>(x))),因此即使您使用auto,它也会被完美转发。

auto f() -> T中,“自动”关键字只是syntactic construct to fill in a type position。它没有其他用途。

事实上,在C ++ 17中,你不能一起使用尾随返回类型的decltype(auto)

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

  

autodecltype(auto) 类型说明符指定一个占位符类型,以后将被替换,可以通过从初始化程序中扣除,也可以通过使用进行显式指定后返回型auto 类型说明符也用于表示lambda是一个普通的lambda。

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

  

autodecltype(auto) 类型说明符用于指定占位符类型,稍后将通过从初始值设定项中扣除来替换该占位符类型。 auto 类型说明符还用于引入具有尾随返回类型的函数类型,或表示lambda是通用lambda(5.1 .5)。 auto 类型说明符也用于引入分解声明(8.5)。

这是DR 1852,请参阅Does a placeholder in a trailing-return-type override an initial placeholder?

实际上,虽然gcc接受decltype(auto) f() -> Twhich is a bug),但clang拒绝,但

error: function with trailing return type must specify return type 'auto',
not 'decltype(auto)'