C++模板内的编译时偏移量
C++ Compile-Time offsetof inside a template
我需要使用带有成员选择器的template
中的offsetof
。我想出了一个办法,如果你能原谅尴尬的语法:
template <typename T,
typename R,
R T::*M
>
constexpr std::size_t offset_of()
{
return reinterpret_cast<std::size_t>(&(((T*)0)->*M));
};
用法并不完美(充其量很烦人):
struct S
{
int x;
int y;
};
static_assert(offset_of<S, int, &S::x>() == 0, "");
static_assert(offset_of<S, int, &S::y>() == sizeof(int), "");
非constexpr
形式更易于使用:
template <typename T, typename R>
std::size_t offset_of(R T::*M)
{
return reinterpret_cast<std::size_t>(&(((T*)0)->*M));
};
明显的缺点是它不是在编译时完成的(但更易于使用):
int main()
{
std::cout << offset_of(&S::x) << std::endl;
std::cout << offset_of(&S::y) << std::endl;
}
我正在寻找的是像非constexpr
变体这样的语法,但仍然是完全编译时的;但是,我无法想出它的语法。我也会对offset_of<&S::x>::value
感到满意(就像其他类型特征一样),但无法弄清楚它的语法魔力。
以下内容应该有效(学分归于这个想法的这个问题的答案):
#include <cstddef>
template <typename T, typename M> M get_member_type(M T::*);
template <typename T, typename M> T get_class_type(M T::*);
template <typename T,
typename R,
R T::*M
>
constexpr std::size_t offset_of()
{
return reinterpret_cast<std::size_t>(&(((T*)0)->*M));
}
#define OFFSET_OF(m) offset_of<decltype(get_class_type(m)),
decltype(get_member_type(m)), m>()
struct S
{
int x;
int y;
};
static_assert(OFFSET_OF(&S::x) == 0, "");
请注意,在 gcc 中,offsetof
宏扩展为可以在编译时使用的内置扩展(见下文)。此外,您的代码调用 UB,它取消引用空指针,因此即使它在实践中可能有效,也无法保证。
#define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
正如 Luc Danton 所指出的,常量表达式不能涉及 C++11 标准的reinterpret_cast
,尽管目前 gcc 接受代码(请参阅此处的错误报告)。另外,我发现了缺陷报告 1384谈论使规则不那么严格,因此将来可能会改变。
相关文章:
- 有没有办法将谓词中的元素偏移量传递给 std 算法?
- 通过指针偏移量访问结构变量值
- 以线程安全的方式转换 C/C++ 中时区名称字符串的时区偏移量
- librdkafka:rd_kafka_assignment 返回分配分区的偏移量 -1001
- 是否通过向封闭对象的地址添加字节偏移量来访问子对象
- 向指针地址添加 20 个字节偏移量
- glMapBufferRange(..) 中的偏移量关系和 glDrawArraysInstanced(..) 中的第一
- 是否有与 C# Structs/StructLayout 等效的功能,C++中的字段偏移量?
- 我的 sumASCII 函数中的此偏移量是多少?
- boost::序列化中的派生类偏移量计算.有效吗?
- RedisGraph 语法错误在偏移量 8 靠近"创建"
- 胎面偏移量的时间复杂度?
- 在编译时计算基类的偏移量
- 获取多重继承中基类的编译时常量偏移量
- 如何在编译时获取成员私有时的偏移量?
- C++模板内的编译时偏移量
- 在 C/C++ 中编译时解析的地址偏移量
- 在编译时确定结构成员字节偏移量
- 如何在编译时输出结构体中成员的偏移量(C/ c++)
- 这是有效的 ANSI C++代码吗?尝试在编译时生成结构成员的偏移量