函数声明中箭头语法的优点

fer*_*kin 4 c++ templates trailing-return-type return-type-deduction

使用的好处是什么

template <typename L, typename R> 
auto getsum(L l, R r) -> decltype(l + r) {return l + r;}
Run Code Online (Sandbox Code Playgroud)

超过

 template <typename L, typename R>
 auto getsum(L l, R r) {return l +  r;}
Run Code Online (Sandbox Code Playgroud)

在模板实例化期间没有自动编译成适当的类型吗?

rus*_*tyx 5

一个优势显然是更短的代码。

但也有缺点:除了仅在 C++14 中可用的自动返回类型推导之外,还存在无法推导返回类型的情况。

假设函数的复杂度略有增加:

template <typename L, typename R>
auto getsum(L l, R r) {
    if (l < 0)
        return 0;
    return l + r;
}
Run Code Online (Sandbox Code Playgroud)

现在以下将无法编译:

int main() {
    auto s = getsum(1L, 2); // error: inconsistent deduction for auto return type: 'int' and then 'long int'
}
Run Code Online (Sandbox Code Playgroud)

我们通过明确指定返回类型来解决这个问题(例如,使用尾随返回类型语法):

auto getsum(L l, R r) -> decltype(l + r) {
    if (l < 0)
        return 0;
    return l + r;
}

int main() {
    auto s = getsum(1L, 2);  // OK
}
Run Code Online (Sandbox Code Playgroud)

  • @einpoklum,不,你不能,因为当时还没有声明 l 和 r 。这就是为什么它是“尾随”的,你可以在声明参数“之后”得到它。 (5认同)

max*_*x66 5

使用 [尾随返回类型语法] 的优点是什么?

一个可能的优势:尾随返回类型是 SFINAE 友好的。

你的getsum()功能,尾随返回类型(-> decltype( l + r )),时间存在的加法运算时,才会启用lr

如果你用几个不支持总和的参数(例如,几个std::vector')调用它,你会得到一个不是错误的替换失败(SFINAE)。

所以getsum()可以调用另一个函数。

以下是一个完整的编译示例,其中“做一些不同的”版本是从 getsum(a, b)

#include <vector>

template <typename ... Ts>
auto getsum (Ts...)
 { /* do something different */ }

template <typename L, typename R> 
auto getsum (L l, R r) -> decltype( l + r )
 { return l + r; }

int main ()
 {
   std::vector<int> a, b;

   getsum(a, b);
 }
Run Code Online (Sandbox Code Playgroud)

但是如果删除尾随返回类型

template <typename L, typename R> 
auto getsum (L l, R r) // <<--- no more tailing return type!!!
 { return l + r; }
Run Code Online (Sandbox Code Playgroud)

代码不再编译,因为您没有替换失败而是一个硬错误。