【问题标题】:Can offsetof be used with a struct type obtained from decltype?offsetof 可以与从 decltype 获得的结构类型一起使用吗?
【发布时间】:2015-11-21 07:24:32
【问题描述】:

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;
}

在 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

它似乎也使 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.

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

【问题讨论】:

    标签: c++ c++11


    【解决方案1】:

    取消引用指针的结果是一个左值(它本身是一个表达式),因此decltype(*this) 给你输入S&amp;

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

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

    ——[...]

    ——否则,如果e是左值,decltype(e)T&amp;,其中Te的类型;

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

    offsetof(std::remove_reference<decltype(*this)>::type, i)
    

    DEMO

    【讨论】:

    • 太棒了,这正是我所需要的。我没有意识到 offsetof 是一位如此出色的类型鉴赏家,以至于仅仅参考一下就将其扔掉了 :)
    • @KubaOber 这不是offsetof 的错;更多的是引用很奇怪。
    • 仔细阅读这些错误消息确实会发现隐藏在它们中的&amp;。但是必须非常仔细地阅读error: offsetof requires struct, union, or class type, 'decltype(*this)' (aka '&lt;anonymous struct at ../qxjs3uu/main.cpp:4:4&gt; &amp;') invalid 才能看到它!
    • @TobySpeight 它还需要理解 struct [...] type 字面意思是一个结构而不是对结构的引用。那正是我不知道的。我已将此用于某些(不一定是好的)使用in this answer
    【解决方案2】:

    它们可以一起使用。举个例子:

    #include <iostream>
    #include <string>
    #include <stddef.h>
    
    int main()
    {
      struct S {
       int a;
       int b;
      };
      S instance;
      std::cout << "offset: " << offsetof(decltype(instance), b) << "\n";
      return 0;
    }
    

    打印偏移量:4

    我认为您的问题源于使用 decltype(*this),根据 C++11 标准的 5.1.1,我不确定它是否会达到您所期望的效果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-01
      • 2014-04-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多