Ala*_*lan 3 c++ visual-c++ language-lawyer compiler-bug
我最近学习了指向成员语法的指针,然后编写了如下所示的程序,msvc 可以编译,但 gcc 和 clang 拒绝。
#include <iostream>
#include <type_traits>
#include <concepts>
struct C
{
int foo()
{
return 5;
}
};
int main()
{
int (C::*ptr)() = &(C::foo); //msvc compiles but not gcc and clang
}
Run Code Online (Sandbox Code Playgroud)
我想知道哪一个是正确的。现场演示
代码格式错误,MSVC 错误。
\n\n\n\n如果操作数是命名某个类的非静态或变体成员的限定 ID,而不是显式对象成员函数,则结果类型为 \xe2\x80\x9c,指向类型为\ xe2\x80\x9d 的类成员的指针并指定.
\nmCCTC::\xe2\x80\x8bm否则,结果的类型为 \xe2\x80\x9c 指向
\nT\xe2\x80\x9d ...
在 中&(C::foo),(C::foo)不是一个限定 ID(C::foo将是一个),而是一个主表达式。
还有[expr.unary.op]/4更明确的:
\n\n\n
&仅当使用显式且其操作数是未括在括号中的限定 ID时,才会形成指向成员的指针。
这背后的基本原理是拥有一种用于形成常规(非成员)指针的语法,以防万一您需要一个(而不是成员指针):
\n#include <type_traits>\n\nstruct A\n{\n int x;\n};\n\nstruct B : A\n{\n int x;\n\n void foo()\n {\n auto f = &A::x;\n static_assert(std::is_same_v<decltype(f), int A::*>);\n\n auto g = &(A::x);\n static_assert(std::is_same_v<decltype(g), int *>);\n }\n};\nRun Code Online (Sandbox Code Playgroud)\nMSVC 也接受这个代码,所以我猜它们只是不符合成员函数,而不是数据成员(这没什么大不了的,因为成员函数&(C::foo)总是非法的)。
| 归档时间: |
|
| 查看次数: |
244 次 |
| 最近记录: |