C ++中编译时常量取决于类型大小的最佳方法是什么?

时间:2015-01-24 00:09:19

标签: c++ templates c-preprocessor compile-time-constant

我在想其中一个:

#if sizeof(size_t) == 8
const size_t foo = 12345;
#elif sizeof(size_t) == 4
const size_t foo = 123;
#else
#error "Unsupported size_t size"
#endif

template <int S> class Foo { static const size_t foo = 0; };
template <> class Foo<8> { static const size_t foo = 12345; };
template <> class Foo<4> { static const size_t foo = 123; };
const size_t foo = Foo<sizeof(size_t)>::foo;

另外,如何使用第二种方法抛出编译时错误?

3 个答案:

答案 0 :(得分:4)

使用类模板的解决方案是一种很好的惯用方法(第一种方法也行不通,所以这两位候选人之间没有竞争)。

要导致编译时错误,只需不要为所有大小定义模板:

template <int S> class Foo;

然后编译器会抱怨模板没有为sizeof(size_t)的违规值定义。

将名称从Foo更改为类似Environment_Where_sizeof_int_is的内容也会有所帮助 - 在实践中,您可以立即理解编译错误。

答案 1 :(得分:1)

使用g++,您还可以使用以下预定义宏:

__SIZEOF_SIZE_T__
__SIZEOF_INT__
__SIZEOF_LONG__

(对于其他类型,依此类推,请参阅documentation获取完整列表。)

例如:

#if __SIZEOF_SIZE_T__ == 8
const size_t foo = 12345;
#elif __SIZEOF_SIZE_T__ == 4
const size_t foo = 123;
#else
#error "Unsupported size_t size"
#endif

答案 2 :(得分:0)

使用类型作为已定义结构的第一个和第二个成员,并获取第二个成员的偏移量以获得第一个成员的大小(假设第一个和第二个成员之间没有填充,第一个成员保证具有与结构相同的地址。)

#define ofs(s,m)   (size_t)&(((s *)0)->m)

typedef struct S_{
size_t a;       /* type to get the size of */
size_t b;       /* make this same type as above */
}S;

int main()
{
size_t c;
    c = ofs(S,b);   /* get size of S.a */
    return(0);
}