我正在为我正在教授的课程安排一个基于C++的作业.我有一个函数,我要向学生出口,我希望他们在他们的课程中的不同点上打电话,这样在评分期间,我们可以拦截这些电话,以确保他们在正确的时间做正确的事情.我不希望该代码在提供的启动文件中执行任何操作,因此我只给了函数一个只有一系列语句的主体,这些语句会转换所有参数void
以禁止编译器有关未使用参数的警告.在这样做的过程中,我遇到了一个我以前从未见过的不寻常的编译器错误,并且对此站点的搜索没有发现任何有用的信息.
这个简化的测试用例可以最好地说明错误:
void iDontUseMyArguments(int a, int b) { (void) a; // Explicit cast to void - totally fine! (void) b; } void iDontEither(int a, int b) { (void) a, b; // Comma expression casted to void, though technically // b isn't casted to void! } void norDoI(int a, int b) { void(a, b); // ERROR! No idea why this isn't okay. } void meNeither(int a, int b) { (void)(a, b); // Comma expression casted to void - totally fine! } void jumpOnBandwagon(int a, int b) { void((a, b)); // Comma expression casted to void - totally fine! }
如您所见,大多数编译得很好.问题出在这个问题上:
void(a, b);
这会触发以下错误:
prog.cpp: In function 'void norDoI(int, int)': prog.cpp:11:11: error: expression list treated as compound expression in functional cast [-fpermissive] void(a, b); ^
我从来没有遇到过这个错误信息,所以我不确定这是告诉我的.
这条线背后的意图
void(a, b);
是是涉及逗号表达式a
和b
然后该浇铸键入void
使用函数样式转换.如您所见,以下变体都有效:
(void)(a, b); void((a, b));
我怀疑这可能与Most Vexing Parse有关,并且这被解释为声明,但我得到的特定错误似乎与此不匹配.
我的问题如下:
究竟为什么这段代码不合法?
编译器认为我想做什么?
确切地说,为什么这些其他变体合法?
小智.. 7
鉴于这种结构:
struct S { S(int, int) {} };
什么S(1, 2)
意思?
答:这意味着你S
从值1
和构造一个类型的对象2
.
鉴于此功能模板:
templateT f() { return T(1, 2); }
什么T(1, 2)
意思?
答:这意味着你构造类型的对象,T
从值1
和2
,如果这是可能的T
是实例的类型S
从第一个问题.
鉴于相同的功能模板,那f
意味着什么?
答:它试图构建一个void
由两个值值1
和2
.这会失败,因为只能将单个值转换为void
.
是否void(1, 2)
意味着什么不同T(1, 2)
的时候T
恰好是void
?
答:不,这意味着完全相同的事情,这就是为什么这是一个错误.
鉴于这种结构:
struct S { S(int, int) {} };
什么S(1, 2)
意思?
答:这意味着你S
从值1
和构造一个类型的对象2
.
鉴于此功能模板:
templateT f() { return T(1, 2); }
什么T(1, 2)
意思?
答:这意味着你构造类型的对象,T
从值1
和2
,如果这是可能的T
是实例的类型S
从第一个问题.
鉴于相同的功能模板,那f
意味着什么?
答:它试图构建一个void
由两个值值1
和2
.这会失败,因为只能将单个值转换为void
.
是否void(1, 2)
意味着什么不同T(1, 2)
的时候T
恰好是void
?
答:不,这意味着完全相同的事情,这就是为什么这是一个错误.