gpt4 book ai didi

模板内的 C++ 编译时偏移量

转载 作者:IT老高 更新时间:2023-10-28 22:38:55 27 4
gpt4 key购买 nike

我有需要使用offsetof来自 template带有成员选择器。我想出了一个办法,如果你能原谅笨拙的语法:

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

我正在寻找的是语法 likeconstexpr种类繁多,但仍然是完全编译时的;但是,我想不出它的语法。我也会很高兴 offset_of<&S::x>::value (就像其他类型特征一样),但无法弄清楚它的语法魔法。

最佳答案

以下应该可以工作(致谢 the answer to this question 的想法):

#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 接受该代码(参见 bug report here)。另外,我发现 defect report 1384哪个谈到让规则不那么严格,所以这可能会在未来改变。

关于模板内的 C++ 编译时偏移量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12811330/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com