C++ 数组访问最麻烦的解析
在查看一些C++03代码时,我发现了一个最让我困惑的解析实例:C++ 数组访问最麻烦的解析,c++,c++03,most-vexing-parse,C++,C++03,Most Vexing Parse,在查看一些C++03代码时,我发现了一个最让我困惑的解析实例: #include <sstream> #include <string> int main(int, char** argv) { std::stringstream ss(std::string(argv[0])); } #包括 #包括 int main(int,字符**argv) { std::stringstream ss(std::string(argv[0]); } 在上面的代码段中
#include <sstream>
#include <string>
int main(int, char** argv)
{
std::stringstream ss(std::string(argv[0]));
}
#包括
#包括
int main(int,字符**argv)
{
std::stringstream ss(std::string(argv[0]);
}
在上面的代码段中,ss
是对函数的声明,该函数接受std::string*
并返回std::stringstream
如何将std::string(argv[0])
解析为std::string*
?
直觉上,我认为
argv[0]
无疑是对argv
的访问,原因是在函数声明的上下文中,编译器将std::string(argv[0])
解释为std::string argv[0]
,即,将零大小数组声明为名为argv
(掩盖main
中的argv
,因为这是一个不同的范围),这相当于逐数组指针衰减
因此,std::stringstream ss(std::string(argv[0])代码>表示与std::stringstream ss(std::string*argv)相同代码>
<>编辑:由于注释中正确注释,在C++中,零大小的数组声明无效,导致程序不正确。使用-pedantic
标志(GCC和clang)编译此代码时,将发出警告。VisualStudio甚至会产生编译错误。但是,对于除0以外的任何其他数组索引,上面的论证仍然有效。我相信这是根据“声明语法类似于表达式语法”原则得出的,并且“数组”参数是指针
以下数组声明是等效的:
int x[1];
int (x)[1];
int (x[1]);
或多或少是因为x[a]
、(x)[a]
和(x[a])
是等价的表达式
因此,
std::stringstream ss(std::string(argv[0]))
std::stringstream ss(std::string argv[0])
std::stringstream ss(std::string*argv)
我无法使用Visual Studio 2015编译此命令,因为argv[0]
显然是一个0大小的数组,类型为argv
。如果使用argv[1]
,我可以得到与您相同的结果。有趣的问题。我认为它相当于std::stringstream ss(std::string argv[])
本身相当于std::stringstream ss(std::string*argv)代码>。我认为有一条准则,如果它看起来像一个声明,那么它就是一条。因此,就像@FrançoisAndrieux从std::string编写的实例化一样,您的实例化不是一个实例化,而是一个std:string数组的声明,链接被设置为正确的时间代码。我花了很长时间才记起我在哪个视频中了解到了这一点,但完全符合你刚才遇到的情况,所以最令人烦恼的解析比我一直认为的更邪恶。。。这不仅是“如果它看起来像一个函数声明,那么它就是一个函数声明”,而且是“如果它看起来像一个无效的函数声明,那么它就是一个函数声明”。。。。omfg@tobi303:看一看语法。它粗略地将数组定义为类型name\u可选[size\u expression]
,对于计算结果为零的表达式,没有特殊的语法规则。但是,因为C++中的表达式求值是图灵完成的,所以它非常困难。在C++中。Ieint(x)
与int x
相同。这就是为什么在这个上下文中,std::string(argv[0])
可以被视为std::string argv[0]
。只需删除std::string
即可避免MVP:std::stringstream ss(argv[0])代码>@RemyLebeau不是0大小的数组无效吗?@RemyLebeau是的,知道了。只是因为C++的另一个怪癖,<>代码>无效的fo(double x(0)){} /代码>很好。
std::stringstream ss(std::string(argv[0]))
<=>
std::stringstream ss(std::string argv[0])
<=>
std::stringstream ss(std::string* argv)