【发布时间】:2023-03-24 08:31:02
【问题描述】:
以下 sn-p 是否使用未定义/未指定/等。行为?
#include <cstddef>
#include <iostream>
#include <string>
class Test {
std::string s1{"s1"}, s2{"s2"};
std::ptrdiff_t offset = (char*)(&s2) - (char*)(this);
public:
std::string& get() { return *(std::string*)((char*)(this) + offset); }
};
int main() {
Test test;
std::cout << Test{test}.get(); // note the copy
}
offset 的目的是指向s1 或s2(在运行时选择)并且不包含用于复制/移动/访问的特殊逻辑。 std::string 这里只是一个非平凡的类的例子。
【问题讨论】:
-
我不明白您要解决什么问题。如果无论如何您都有一个“哨兵”值,只需将该哨兵(您的偏移成员)本身设为一个指针,直接指向您要访问的内容。否则,这不只是对offsetof 宏的奇怪重复,可能不是正确的指针算术吗?
-
这里有
offsetof宏。但它仅对非标准布局的类型有条件地支持(并且您的类不是标准布局)。 -
用
std::string * alias = &s2;代替std::ptrdiff_t offset = (char*)(&s2) - (char*)(this);,然后get变成return *alias; -
@passing_through 使用成员指针而不是对象指针。然后,它不需要重置。
标签: c++ class language-lawyer offset undefined-behavior