在 C++11 函数中使用尾随 return 类型的优点

Advantage of using trailing return type in C++11 functions

与普通的 return 类型相比,在 C++11 中指定尾随 return 类型有什么好处?在此处查看 foo1foo2

int foo1() {
    return 1;    
}

auto foo2() -> int {
    return 1;    
}

int main() {
    foo1();
    foo2();
}

在此示例中,它们的意思完全相同。

但是,始终如一地使用尾部 return 类型形式有一些优点(Phil Nash 称这些为 "East End Functions",因为 return 类型位于东端)。

  1. 使用参数。显然,当使用参数来确定 return 类型时,您 必须 使用尾随 return 类型。

     template <typename T>
     auto print(T const& t) -> decltype(std::cout << t) { return std::cout << t; }
    
  2. 名称查询。在尾随 return 类型中,名称查找包括成员函数定义的 class 范围。这意味着如果你想 return 一个嵌套的 class:

    ,你不必重新输入 class
     Type C::foo() { ... }         // error: don't know what Type is
     C::Type C::foo() { ... }      // ok
    
     auto C::foo() -> Type { ... } // ok
    
  3. 同样,为了定义成员函数,其中 class 名称出于某种原因必须在全局命名空间中消除歧义,并且 return 类型是 class:

     D ::C::foo() { ... }         // error, parsed as D::C::foo() { ... }
    
     auto ::C::foo() -> D { ... } // ok
    
  4. 信息排序更加合理。假设您想编写一个函数 to_string,它接受一个 int 和 return 一个 string。这是一种非常明智的措辞方式。函数名称、参数、return 类型。你不会说你想写一个名为 to_stringstring-returning 函数接受一个 int。这是一个尴尬的信息顺序。名称是最重要的,其次是参数,然后是 return 类型。尾随 return 类型的形式可以让您更好地对这些信息进行排序。

在某些情况下尾随-return-类型是强制性的,在某些情况下它是有帮助的,在某些情况下它做同样的事情。除了简单的字符数之外,没有其他原因导致更糟糕的情况。

此外,从数学上讲,我们习惯于将函数视为 A -> B 而不是 B(A),因此 auto(*)(A) -> B 是一个接受 A 的函数指针return BB(*)(A).

更接近那个观点

另一方面,写 auto main() -> int 看起来很可笑。

但老实说,这主要是因为不熟悉。这本身并没有什么可笑的。如果有的话,有点不幸的是语言在这里使用 auto 作为声明函数的方式 - 不是因为它太长(即其他一些语言使用 fun 甚至 fn) -但是因为它与 auto 的其他用途并没有真正的区别。如果换成func,我觉得会更好(虽然现在改也没什么意义)


最终,这纯粹是基于意见。只需编写有效的代码。