auto main() -> int的含义是什么?

37

我在一段关于C++11的视频中偶然发现了下面的代码片段,其中作者使用了

auto main()->int

我不理解这个。我尝试使用-std=c++11g++中编译它,结果可以运行。 有人能解释一下这里发生了什么吗? 我试着搜索“auto main()->int”,但没有找到任何帮助。

3个回答

57

C++11 引入了一种称为 尾置返回类型 的表示方法:如果使用 auto 来声明函数,那么返回类型会在参数后面加上 ->,也就是说,这只是将 main() 声明为返回 int

尾置返回类型的主要意义在于函数模板,现在可以使用函数参数和 decltype() 一起来确定返回类型。例如:

template <typename M, typename N>
auto multiply(M const& m, N const& n) -> decltype(m * n);

这段代码声明了函数 multiply() 返回 m * n 的类型。在 multiply() 前使用 decltype() 是无效的,因为 mn 还没有被声明。

虽然这种表示法主要用于函数模板,但同样的符号也可以用于其他函数。在某些条件下,使用 C++14,当函数是由 auto 引入时,尾随返回类型甚至可以省略。


23
声明main函数这样做的优势是什么? - PaperBirdMaster
9
@PaperBirdMaster:我并不声称有什么优势。然而,这是允许的,且并不比其他选择更糟。 - Dietmar Kühl
2
抱歉造成误解,我并不是在说你认为在main函数中使用尾随返回类型(TRT)有优势,我只是在问(并且想知道)在这种情况下使用TRT是否有任何优势...我认为包括这个解释(如果有的话)会很好地改善答案。 - PaperBirdMaster
1
如果返回类型是 intboolcharvoid 或者模板类型少于 5 个字符,那么实际上并没有什么优势。但它确实使得每个函数名从相同的文本列开始。 - CTMacUser
1
TRT的主要优势是它对SFINAE(http://en.cppreference.com/w/cpp/language/sfinae)友好。例如,如果我编写一个函数`template <typename T> auto size(T x) -> decltype(x.size()) {return x.size();},那么只有当x.size()`是有效表达式时,它才会参与重载决议。如果不是这种情况,编译器将搜索另一个重载。 - sv90
显示剩余5条评论

22

这是一种统一的函数声明语法,在C++11中引入了尾随返回类型

您不能使用任何其他语法来定义lambda表达式,对于依赖于参数的结果类型的函数模板也非常方便。

如果您想选择一种单一的语法(我认为这是一个好主意),那么您没有选择:旧语法不能用于lambda表达式。

做出这样的决定的原因包括:

  • 唯一语法

  • 函数名称始终在同一位置可视化,支持快速扫描代码。

  • 同样适用于结果类型,易于视觉识别(此外,当它是成员函数类中定义的类型时,您无需限定它)。

反对的理由包括一些额外的冗长、使用不理解此语法的旧编译器、任何新东西都会感到可怕、不舒适和奇怪。


4
我会尽力进行翻译: 我即使在正常代码中也会使用这种语法,目的是为了一个点:函数名称始终在视觉上处于同一位置,支持快速扫描代码。对我们人类来说很容易通过一点努力就能找出函数的名称,因为它紧随着“auto”之后被写出来。所有函数的呈现方式在视觉上都是相同的。 - Nawaz
13
个人认为auto main() -> int是一个可怕的想法。*"嗯,这只是一种语法而已。"* 除了那些已经存在的数百万行代码之外。无论如何,它都会与旧代码混合在一起成为一种混合语法。*"函数名称始终位于同一位置,支持快速扫描代码。"* 我使用我的IDE生成的大纲,这样甚至更快速地扫描。*"对于结果类型也是如此,易于视觉识别。"* 为什么在auto main() -> int中更容易找到返回类型,而不是在int main()中,其中返回类型就在前面,我不必阅读任何内容就可以找到它? - Ali
4
@Ali:关于“为什么在auto main() -> int中更容易找到返回类型,而在int main()中返回类型就在最前面,我不需要阅读任何内容就能找到它”的问题,当你发现攻击一个稻草人的论点是必要的时候,你实际上是承认自己没有真正的论点。然而,感到恐惧和厌恶是不做某事的合理理由。无论这些感觉有多么不合理,它们确实会影响一个人的行动,一个人可能会因为不得不与它们斗争而变得不那么有效率。 - Cheers and hth. - Alf
3
“你正在攻击我”。“我没有攻击任何人/任何事物。我留下了一个评论,表示我不同意,并给出了我的理由。你仍然没有给我任何理由,说明在auto main() -> int中找到返回类型比在int main()中更容易。” - Ali
2
@Ali:我认为 auto main() -> int 这种写法没有任何问题。 - Cheers and hth. - Alf
显示剩余9条评论

12

它被称为尾返回类型。在使用模板的泛型代码中特别有用,其中返回类型取决于涉及其他一些模板参数的表达式。 它还用于lambda表达式。

这里是一个例子:

template<typename T, typename U>
auto add(T t, U u) -> decltype(t+u)
{
   return t + u;
}

在这里,返回类型取决于表达式 t+u。因此,无论表达式的类型是什么,函数的返回类型也是相同的,这由 decltype(t+u) 指示。


1
那真的很有帮助! - Param Siddharth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接