Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/148.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 数组访问最麻烦的解析_C++_C++03_Most Vexing Parse - Fatal编程技术网

C++ 数组访问最麻烦的解析

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]); } 在上面的代码段中

在查看一些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]);
}

在上面的代码段中,
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++中。Ie
int(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)