5

有效的 C++main签名如下:

int main()
int main(int argc, char *argv[])
int main(int argc, char **argv)

但不允许声明main采用初始化列表:

int main(std::initializer_list<char *> args)

AFAIK初始化器列表可以实现为一对指针或一个指针(这可能是argv参数)加上一个长度(这可以从argc参数推导出来),它的存储可以是自动的、临时的或静态的只读存储器视情况而定

所以我认为 anstd::initializer_list<char *>可以毫无问题地处理和管理命令行参数,然后我想知道为什么main在 C++11 标准上的初始化程序列表获得批准后没有添加这个假设的签名,因此我我在问:

  • 允许初始化列表作为main唯一参数可能会带来哪些缺点或问题?(我想不出任何)。
  • 向标准委员会提出此添加(或任何其他更改)的正确方法是哪种?
4

3 回答 3

4

尽管在程序中有两种指定方式main(),但大多数(全部?)C++ 运行时的当前实现都main()以相同的方式调用函数(它们传递参数,(int, char *[])而与main()声明方式无关)。您的建议将要求所有实现的 C++ 运行时来确定正在使用哪种main()程序,并调用正确的main(). 如果你真的想要这个功能,你总是可以提供一个实现main(int, char *[]),将参数转换为一个初始化列表,如对象(例如vector<>),然后调用你选择的新入口点函数。

标准 C++ 网站上描述了提交提案的过程。基本步骤是:(1)在他们的 Usenet 组/邮件列表中浮动这个想法;(2) 起草提案,征求反馈意见,并据此更新提案;(3) 重复该过程,直到提案被接受。

于 2013-09-30T17:07:19.903 回答
4

值得注意的是,一个库(但不是标准 C++ 库,根据 3.6.1 [basic.start.main] 第 2 段,第一句:“实现不应预定义main函数。”)可以只定义函数main()并实现它以合适的方式,例如,调用app_main()

#include <initializer_list>
#include <string>
#include <vector>
extern int app_main(std::vector<std::string> const&);

int main(int ac, char* av[]) {
    return app_main(std::vector<std::string>(av, av + ac));
}

由于main()不能重载(根据 3.6.1 [basic.start.main] 第 2 段,第二句:“此函数不得重载。”)入口点需要不同的名称。由于std::initializer_list<T>除了 using 之外无法构造,因此需要使用{ ... }不同的类型。std::initializer_list<T>在这样做的同时,上面的实现也选择将它们char*变成std::string对象。

要使用上述函数,应用程序只需实现app_main()并调用它:

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include <cstdlib>

int app_main(std::vector<std::string> const& args) {
    std::cout << "received the arguments: ";
    std::copy(args.begin(), args.end(),
              std::ostream_iterator<std::string>(std::cout, " "));
    return EXIT_SUCCESS; // return statement can't be omitted, of course
}
于 2013-09-30T18:06:52.000 回答
0

我认为这是出于对 C 兼容性的考虑,而不是技术原因。从 C 继承了很多东西。

于 2013-09-30T16:57:25.910 回答