我有一个指向成员的指针,例如
#include <cstdint>
struct Foo {
uint64_t x;
};
void test(Foo& f, uint64_t Foo::* p) {
(f.*p) = 5;
}
效果很好。然而,假设我实际上想生成一个指向
x
后半部分的指针(我们安全地假设小端):
#include <cstdint>
struct Foo {
uint64_t x;
};
void test32(Foo& f, uint32_t Foo::* p) {
(f.*p) = 5;
}
void test(Foo& f, uint64_t Foo::* p) {
test32(f, reinterpret_cast<uint32_t Foo::*>(p) + 1);
}
此操作失败并出现以下错误:
error: invalid operands of types 'uint32_t Foo::*' {aka 'unsigned int Foo::*'} and 'int' to binary 'operator+'
这是为什么,我该如何进行这个指针运算?
(是的,我知道这似乎是一个坏主意。请不要发表“你不应该这样做”的评论。)
这是为什么
因为标准明确不允许在指向成员的指针上进行这种算术。首先请注意,指向成员的指针实际上不是指针。
现在,来自 expr.add:
对于加法,两个操作数都应具有算术类型,或一个操作数应是指向完全定义的对象类型的指针,另一个操作数应具有整型。
重要的是,短语“指向完全定义的对象类型的指针”不包括“指向成员的指针”,如basic.compound#3:
除了指向静态成员的指针之外,引用“指针”的文本不适用于指向成员的指针。允许指向不完整类型的指针,尽管对它们可以执行的操作有限制([basic.align])。