首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C++类/结构数据成员偏移量作为常量表达式

C++类/结构数据成员偏移量作为常量表达式
EN

Stack Overflow用户
提问于 2011-02-04 15:05:05
回答 3查看 1.8K关注 0票数 2

获取数据成员的偏移量是非常容易的:

代码语言:javascript
运行
复制
#define MEMBER_OFFSET(Type, Member) \
    ((unsigned long)(((char *)&((Type *)0)->Member) - (char *)0));

我想让它成为一个常量的编译时表达式(或者使用类型特征)。例如,使用成员偏移来实现基于SFINAE的解决方案,使用静态断言等等。

更新:问题是-如何使其成为编译时表达式。而不是它是否适用于POD类型,或者C库中是否有标准宏等。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-02-04 18:52:29

虽然我无法理解您的编译器是什么,但以下代码可以由VC8、ideone(gcc-4.3.4)和Comeau online编译:

代码语言:javascript
运行
复制
struct A { int i; };
template< size_t > struct S;

int main() {
  S< offsetof( A, i ) > *p;
}

Gcc有__offsetof__扩展。VC似乎有能力采取一个非编译时间常数的模板参数奇怪。至于Comeau,不幸的是,我对Comeau的offsetof内部一无所知。

顺便说一句,虽然这不会直接回答您的问题,但对于SFINAE而言,由于成员指针常量可以用作模板参数,您可以专门编写如下内容:

代码语言:javascript
运行
复制
struct A {
  int i, j;
};

template< int A::* > struct S;
template<> struct S< &A::i > { static char const value = 'i'; };
template<> struct S< &A::j > { static char const value = 'j'; };

int main() {
  cout<< S< &A::i >::value <<endl;
  cout<< S< &A::j >::value <<endl;
}

希望这能有所帮助。

票数 3
EN

Stack Overflow用户

发布于 2011-02-04 15:09:37

C标准库已经有了offsetof,它可以尝试这样做(但是您可以不用UB使用它)。不幸的是,将其应用于非POD类型仍然会导致未定义的行为,因此对于许多C++来说,它仍然是无用的。

票数 1
EN

Stack Overflow用户

发布于 2011-02-04 19:08:23

首先,把分号放在宏中是个坏主意--它不能用于一个大表达式中。

其次,如果有专门为指针设计的非常好的类型(即stdint.h中提供的size_t和ssize_t ),那么使用size_t是个坏主意。当使用32位和64位架构时,这些类型尤其有用-- GCC对printf "%zu“进行了扩展,以使用正确的单词大小。

G++在编译时计算这一点,至少在-O2和-O3中是这样的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4899476

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档