c++中奇怪的解析:int f(int(arg))等价于int f(int arg)——有人能解释一下吗?
Weird parse in C++: int f(int(arg)) equivalent to int f(int arg) - can anyone explain it?
这是我的一个同事在试图构造一个只有一个参数的对象时发现的:
char testString[] = "test string";
...
MyClass instance(QString(testString));
他们意识到这样一种情况:如果你用函数风格的习惯用法构造一个单参数,它将被解析为一个前声明的函数,例如
char test[] = "hello";
MyClass instance1(0, test) //constructs an object
MyClass instance2(test) //invalidly forward-declares a function
但是他们被他们认为应该工作的东西难住了,因为它在括号内包含了函数风格的强制转换,或者单参数构造函数调用。
我已经发现他们的构造函数调用被解析为:
MyClass instance(QString testString);
没有将变量testString传递给强制转换操作符,而是声明了一个带有同名形参的函数。我的问题是,为什么会这样?它似乎允许参数名被括号包围
这是我的一个同事发现的
不,它是几十年前"发现"的,是语言中一个非常著名的怪癖。
- https://en.wikipedia.org/wiki/Most_vexing_parse
我的问题是,为什么会这样?它似乎允许参数名被括号括起来。
。C声明语法没有规定不允许这种特殊情况。在一般情况下,它对于像这样的更复杂的结构很有用:
void foo(int (*func)(char));
// (takes a pointer to a function returning int and taking char, bool)
// as opposed to:
void foo(int *func(char));
// (takes a function returning int* and taking char)
// as this is literally equivalent to the clearer:
void foo(int* func(char));
, c++中:
void foo(int (&array)[5]) {}
// (takes a reference to an array of five integers)
// as opposed to:
void foo(int &array[5]) {}
// (takes an array of five `int&`s ... and fails to compile accordingly)
对于您的具体情况,这是公认的笨拙的解决方案:
MyClass instance((QString(testString)));
// ^ ^
或者,自c++ 11以来更有用的:
MyClass instance(QString{testString});
// ^ ^
这实际上是引入统一初始化语法的驱动因素之一。
附录
如果你用函数风格的习惯用法构造一个参数,它将被解析为一个前向声明的函数,例如
MyClass instance2("hello") //invalidly forward-declares a function
这种说法根本不正确。
另外,char *testString = "test string";
已经被弃用了17年,非法使用了4年。
在c++和C语言中,声明符可以用任意数量的圆括号括起来:
int a;
int (b);
int ((c));
int f(int (x));
这主要用于区分函数指针声明符和返回指针类型的函数声明符。例如,这里的f
是指向一个函数的指针,该函数接受一个int
并返回一个int
:
int (*f)(int x);
换句话说,如果x
是int
,则(*f)(x)
是int
。而在这里,f
是一个接受int
并返回指向int
的指针的函数:
int *f(int x);
也就是说,如果x
是int
,那么*f(x)
就是int
。
相关文章:
- 为什么在全局范围内使用"extern int a"似乎不行?
- int(c) 和 c-'0' 之间的区别。C++
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 为什么野牛仍在使用"int yylex(void)",却找不到"int yylex(YYS
- 有符号的int和int-有没有一种方法可以在C++中区分它们
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 如何在 C 中正确使用 libiconv 使其不会报告"Arg list too long"?
- 是否可以从int转换为enum类类型
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- 向量 <int> a {N, 0} 和 int arr a[N] = {0} 的时间复杂度有什么区别
- 'short int'持有的值溢出,但"自动"不会溢出?
- 如何在C++中将一个无符号的 int 转换为两个无符号的短裤?
- 调用'begin(int [n])'没有匹配函数
- 没有显式声明的int[]中的foreach
- 在c++中访问int到类对象的映射时出错
- 为什么我无法更改"set<set>"循环中的值<int>
- 长 长 int 不要 长 int 好
- C++程序在循环后给出奇怪的int值
- 如何计算数据类型的范围,例如int
- c++中奇怪的解析:int f(int(arg))等价于int f(int arg)——有人能解释一下吗?