有效的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
参数推断出来(,其存储可以是自动、临时或静态只读内存,具体取决于情况。
所以我认为std::initializer_list<char *>
可以毫无问题地处理和管理命令行参数,那么我想知道为什么在批准 C++11 标准的初始值设定项列表后没有添加这个假设的main
签名,因此我问:
- 允许初始值设定项列表作为唯一的参数
main
可能有什么缺点或问题?(我想不出任何(。 - 向标准委员会提出此添加(或任何其他更改(的正确方法是什么?
方法可以在程序中指定main()
,但大多数(所有?(C++运行时的当前实现都以相同的方式调用main()
函数(无论main()
如何声明,它们都(int, char *[])
传递参数(。您的建议需要所有实现的C++运行时来确定程序正在使用哪种main()
,并调用正确的main()
。如果您确实想要此功能,则始终可以提供main(int, char *[])
的实现,该实现将参数转换为初始值设定项列表(如 对象((如 vector<>
(,然后调用您选择的新入口点函数。
提交提案的过程在标准C++网站上进行了描述。基本步骤是:(1(在他们的Usenet组/邮件列表中提出想法;(二(起草提案,征求反馈意见,并相应更新提案;(3(重复该过程,直到提案被接受。
值得注意的是,一个库(但不是根据 3.6.1 [basic.start.main] 第 2 段第一句:"实现不应预定义main
函数"的标准C++库(可以只定义函数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>
不能使用{ ... }
以外的构造,因此需要使用与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
}
这是由于C兼容性的考虑,而不是技术原因。有很多东西是从C继承的。