C++23带void显式对象参数的成员函数:哪个编译器行为合规?
C++23显式this参数为void时的编译器行为分歧
自C++23起,未声明cv限定符或引用限定符的非静态非虚成员函数,若首个参数不是函数参数包,可声明带前缀关键字this的显式对象参数。但当这个显式对象参数的类型为void时,各编译器的调用行为出现了分歧:
代码示例
struct A { void f(this void) {} }; // 所有编译器均允许此代码 auto p = &A::f; int main() { // GCC和MSVC允许该调用 p(); // Clang允许该调用 A{}.f(); }
各编译器的错误反馈
- Clang拒绝
p();,报错信息:error: called object type 'void (A::*)()' is not a function or function pointer - GCC和MSVC拒绝
A{}.f();,分别提示:- GCC:
note: candidate expects -1 arguments, 0 provided - MSVC:
error C2660: 'A::f': function does not take 0 arguments
- GCC:
标准符合性分析
根据C++23标准的定义,显式this参数为void时,该成员函数的语义是不需要绑定类实例即可调用,本质上等价于“无对象依赖”的成员函数:
- 对于
A{}.f();:这类调用试图传递一个隐含的类实例给不需要对象参数的函数,属于不符合语义的调用——GCC和MSVC拒绝该调用的行为更贴合标准逻辑。 - 对于
p();:指向这类函数的成员指针,应该允许直接调用而无需绑定实例——GCC和MSVC允许该调用的行为符合显式this为void的设计意图,而Clang将其视为普通成员函数指针的处理方式不符合标准规定。
综上,GCC和MSVC的行为更符合C++23标准的要求。
内容的提问来源于stack exchange,提问作者Fedor
相关产品推荐
相关产品推荐

