在编写涉及noexcept
的代码时,我犯了一个拼写错误,并惊讶地发现该程序是用gcc编译的,而不是用clang和msvc编译的。演示
struct C
{
void func() noexcept
{
}
void f() noexcept(noexcept(C::func)) //gcc compiles this but clang and msvc rejects this
{
}
};
所以我的问题是哪一个编译器就在这里(如果有的话(?
程序是格式错误,gcc接受代码是错误的,因为我们无法在未赋值的上下文(如decltype
、sizeof
或noexcept operator
(中命名非静态成员函数。
这可以从expr.prim.id:中看出
只能使用表示类的非静态数据成员或"非静态成员函数"的
id-expression
:
- 作为类成员访问的一部分,其中对象表达式引用成员的类或从该类派生的类,或者
- 形成指向成员的指针([expr.unary.op](,或
- 如果该id表达式表示非静态数据成员,并且它出现在未赋值的操作数中
[示例:
struct S { int m; }; int i = sizeof(S::m); // OK int j = sizeof(S::m + 42); // OK
--结束示例]
由于id表达式C::func
表示非静态成员函数,但不属于列出的三个类别中的任何一个,因此程序是格式错误的。
以下是gcc错误:
GCC编译noexcept运算符中非静态成员函数的无效使用
还要注意,如果C::func
表示一个非静态数据成员(而不是成员函数(,那么由于上面列表中的第三个项目符号,程序就已经形成了。演示
同样,如果你写&C::func
,它也会起作用(格式良好(,因为上面引用的列表中有第二个项目符号。