C++23显式对象成员函数重载的跨编译器合规性确认
C++23 显式对象参数与成员函数重载的合规性分析
下面针对三个显式对象参数和普通成员函数的重载场景,结合C++23标准逐一分析正确行为,同时对比各编译器的差异:
场景#1:this const C 对应函数与 const 成员函数
代码示例
struct C { void j(this const C); void j() const ; //#1: Clang拒绝,GCC和MSVC通过 };
编译器行为
- Clang报错:
:3:10: 错误:类成员无法重复声明 3 | void j() const ; //#1: Clang拒绝,GCC和MSVC通过 | ^ :2:10: 注意:之前的声明在此处 2 | void j(this const C); |
- GCC、MSVC:编译通过
合规性分析
按C++23标准的规定:
- 非引用类型的显式对象参数会被自动调整为左值引用,所以
void j(this const C)等价于void j(const C&)。 - 两个函数的签名完全不同:前者的参数列表是
(const C&),后者是不带显式参数的const成员函数(隐含const C*类型的this指针)。 - 签名不同的成员函数属于合法重载,因此GCC和MSVC的行为符合标准,Clang的报错是错误的。
场景#2:this C 对应函数与带普通C参数的成员函数
代码示例
struct C { void f(this C ); void f(C); //#2: EDG拒绝,Clang、GCC和MSVC通过 };
编译器行为
- EDG:编译拒绝
- Clang、GCC、MSVC:编译通过
合规性分析
按C++23标准的规定:
- 显式对象参数
this C会被调整为左值引用,即等价于void f(C&)。 - 第二个函数
void f(C)的参数是按值传递的C,和前者的C&参数类型完全不同。 - 两者签名存在差异,属于合法重载,因此Clang、GCC、MSVC的行为符合标准,EDG的拒绝是错误的。
场景#3:this const C& 对应函数与 const 成员函数
代码示例
struct C { void k(this const C&); void k() const ; //#3: EDG通过,Clang、GCC和MSVC拒绝 };
编译器行为
- EDG:编译通过
- Clang、GCC、MSVC:编译拒绝
合规性分析
按C++23标准的规定:
- 显式对象参数
this const C&无需调整,参数类型就是const C&;而void k() const是不带显式参数的const成员函数(隐含const C*类型的this指针)。 - 两者的参数列表不同,签名存在差异,属于合法重载。
- 另外标准明确:带显式对象参数的成员函数不能额外添加cv/ref限定,但此场景中两个函数分别使用显式对象参数和传统cv限定的写法,并不冲突。因此EDG的行为符合标准,其他编译器的拒绝是错误的。
内容的提问来源于stack exchange,提问作者user20562802
相关产品推荐
相关产品推荐

