Гео*_*нов 5 g++ visual-c++ language-lawyer clang++ c++17
这是一个例子:
struct TestClass {
void testFunction() const {}
static TestClass* ptr_;
constexpr static auto funcPtr = +[](){ ptr_->testFunction(); };
};
TestClass* TestClass::ptr_ = new TestClass();
int main() {
TestClass::funcPtr();
delete TestClass::ptr_;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这会在gcc
and 中编译,不会在clang
and中编译msvc
。哪个编译器是正确的?这是一个错误吗gcc
?
这是clang
错误消息:
<source>:4:46: error: member access into incomplete type 'TestClass'
4 | constexpr static auto funcPtr = +[](){ ptr_->testFunction(); };
| ^
<source>:1:8: note: definition of 'TestClass' is not complete until the closing '}'
1 | struct TestClass {
| ^
1 error generated.
Compiler returned: 1
Run Code Online (Sandbox Code Playgroud)
msvc
错误信息如下:
example.cpp
<source>(4): error C2027: use of undefined type 'TestClass'
<source>(1): note: see declaration of 'TestClass'
<source>(4): error C2131: expression did not evaluate to a constant
<source>(4): note: failure was caused by call of undefined function or one not declared 'constexpr'
<source>(4): note: see usage of 'TestClass::<lambda_bdad2d00eade3d9eccb85c581305196c>::operator void (__cdecl *)(void)'
Compiler returned: 2
Run Code Online (Sandbox Code Playgroud)
这是CWG 1836,该计划按照当前措辞格式良好,如下所述。
首先请注意->
(and .
) 是成员访问运算符,因此我们转到expr.post#expr.ref:
否则,对象表达式应为类类型。类类型应是完整的,除非类成员访问出现在该类的定义中。
由于ptr_->testFinction()
是在类的定义之内,因此此处的类类型不需要完整。
这是已确认的 clang 错误:
Clang 拒绝涉及类型不完整的成员访问运算符的有效程序 CWG 1836