可以偏移与从decltype获得的结构类型一起使用吗?

Rei*_*ica 4 c++ c++11

可以offsetof与通过decltype?获得的类型一起使用?这些案例中的任何一个都是有效的C++ 11吗?

struct S {
  int i;
  int j { offsetof(decltype(*this), i) };  // case 1
  S() : i(offsetof(decltype(*this), j)) {}; // case 2
} inst1;

int main() {
  struct {
    int i;
    int j { offsetof(decltype(*this), i) }; // case 3
  } inst2;
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

它们都没有在Apple LLVM 6.0版(clang-600.0.57)(基于LLVM 3.5svn)下编译,但错误

error: offsetof requires struct, union, or class type, 
'decltype(*this)' (aka '<anonymous struct at ../qxjs3uu/main.cpp:4:4> &') invalid
Run Code Online (Sandbox Code Playgroud)

它似乎也崩溃MSVC 19.00.23106.0(x86)内部错误:

Compiled with  /EHsc /nologo /W4 /c
main.cpp
main.cpp(3): error C2062: type 'S &' unexpected
[...]
main.cpp(4): fatal error C1903: unable to recover from previous error(s); stopping compilation
Internal Compiler Error in c:\tools_root\cl\bin\i386\cl.exe.  You will be prompted to send an error report to Microsoft later.
Run Code Online (Sandbox Code Playgroud)

我是否想过没有测试用例编写者想到的东西?

Pio*_*cki 6

取消引用指针的结果是左值(并且它本身是一个表达式),因此decltype(*this)为您提供类型S&:

§7.1.6.2[dcl.type.simple]/p4:

表示的类型decltype(e)定义如下:

- [...]

- 否则,如果e是左值,decltype(e)则是T&,T其类型e;

要将其用作参数offsetof,您需要从说明decltype()符中获取的类型中删除引用:

offsetof(std::remove_reference<decltype(*this)>::type, i)
Run Code Online (Sandbox Code Playgroud)

DEMO

  • 仔细阅读这些错误消息确实揭示了"&"隐藏在它们中.但是必须读取`错误:offsetof需要struct,union或class类型,'decltype(*this)'(又名'<anonymous struct at ../ qxjs3uu/main.cpp:4:4>&')无效仔细看看吧! (2认同)