我在某些课程中使用
offsetof
(这是我别无选择的选择)。这个宏需要一个变量的名称,我想给用户命名它的可能性。
template <typename T>
constexpr ptrdiff_t shift = offsetof(T, name);
我的意思是这样的:
// the user writes this in his code
#define NAME name
// somewhere in the code inaccessible to the user
template <typename T>
constexpr ptrdiff_t shift = offsetof(T, NAME);
但是,编译器很难简单地替换名称。那么,我的出路是什么?
我的代码:
#include <iostream>
// #defined by the user
#define NAME name
// this class is #included
template <typename T>
struct B {
static const ptrdiff_t shift = offsetof(T, NAME); // gives an error but compiles
void f() {
std::cout << shift;
}
};
// user's class
struct A {
B<A> name;
};
编译器并不费力去替换
NAME
。您可以通过检查预处理后的输出来看到这一点(-E
对于 clang 和 gcc)。
该错误抱怨
A
是 offsetoff(A,name)
中的不完整类型。
问题是您设计中的缺陷:
struct A {
B<A> name;
};
B
模板要求 A
是完整类型。按照您定义 A
的方式,需要 B<A>
才能完整定义成员 name
。这是一个圆圈,A
需要B<A>
才能完成,而B<A>
需要A
才能完成。一种解决方案是不在 shift
中包含 B
,但首先定义:
struct A {
B name;
};
然后可以使用
offsetof
宏来确定 name
在 A
中的偏移量。