为什么不能推断出主要的返回类型?

Lig*_*ica 32 c++ return-type-deduction c++14

正如预期的那样,C++ 11中的以下内容失败,因为该语言没有bog标准函数的返回类型推导:

auto main()
{
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

但是,C++ 14确实如此,所以我无法解释以下错误(在GCC trunk,clang 3.8和Visual Studio 2015中具有相同的结果):

error: 'main' must return 'int'
Run Code Online (Sandbox Code Playgroud)

我没有看到标准中的一个段落,禁止返回类型扣除main?或者两个编译器都不兼容?

(对于它的价值,我永远不会真的这样做.int main()为了胜利......)

Som*_*ude 23

阅读C++ 17草案 §3.6.1/ 2:

...它应具有声明的返回类型int,...

所以是的,我会说它被禁止使用扣除.


上一篇C++ 14草案中几乎完全相同的措辞(与C++ 17草案相同的部分):

它应具有声明的返回类型int,...


在阅读评论和其他答案后,只是个人反思这背后的可能原因.(我认为)不允许推理返回类型推导,因为编译器在查看return语句之前不知道返回类型.int可能会返回其他类型(可隐式转换为),这会导致推断类型错误.预先声明返回类型(通过正常的老式方式,或使用尾随返回类型)将在声明函数时设置类型,然后由编译器检查然后是正确的.

至于允许类型别名,它们只是一种类型的别名.所以允许例如

typedef int my_type;
my_type main() { ... }
Run Code Online (Sandbox Code Playgroud)

真的没什么不同

int main() { ... }
Run Code Online (Sandbox Code Playgroud)

  • N4296不是"最后的C++ 14草案".这是第一个带有折叠表达式的C++ 17草案.C++ 14 DIS是N3937(N3936具有相同的内容,但有不同的封面); IS是N4141(N4140是IS +编辑修正). (4认同)
  • @ JohannesSchaub-litb:嘿.好吧,类型`MyInt` _is_类型`int`,所以...... (2认同)

isa*_*nae 17

从3.6.1/2(强调我的):

[...]它应具有声明的返回类型int,但其类型是实现定义的.

如果auto在没有尾随返回类型的情况下使用,则函数的声明返回类型仍然是auto,即使推断的返回类型可能是其他类型.声明推断之间的差异在标准中没有明确说明,但7.1.6.4/7可能会有所启发:

return在使用包含占位符类型的返回类型声明的函数中发生语句时,推导出的返回类型[...]由其初始化程序的类型确定.在return没有操作数或类型操作数的情况下void,声明的返回类型应为auto,推导的返回类型为void.

我的理解是:

auto main(){ return 0; }
Run Code Online (Sandbox Code Playgroud)

声明的返回类型仍然是auto,虽然推断返回类型int.按照上述3.6.1/2,则声明的返回类型main 必须int.因此,这是不正确的.

但是,尾随返回类型被视为声明的返回类型.从7.1.6.4/2开始:

如果函数声明包含trailing-return-type(8.3.5),则trailing-return-type指定函数的声明返回类型.

$ cat a.cpp
auto main() -> int {}
$ g++ -Wall -std=c++14 a.cpp
$
Run Code Online (Sandbox Code Playgroud)

所有引用在C++ 14和C++ 17中都是相同的.

  • 真正的问题是为什么return语句中的推断类型不指定函数的声明返回类型. (2认同)

And*_*dyG 8

从3.6.1开始[basic.start.main]

1程序应包含一个名为main的全局函数,它是程序的指定开始....
2实现不应预定义主函数.此功能不应过载.它应该具有int类型的声明返回类型,否则其类型是实现定义的...

如果标准是限制扣除,那么我认为"声明返回类型int"的措辞就是它.