从"子项"项指针获取"父""std::tuple"
Getting "parent" `std::tuple` from "children" item pointers
struct Apple { };
struct Banana { };
struct Peach { };
using FruitTuple = std::tuple<Apple, Banana, Peach>;
template<typename TTuple, typename TItem>
TTuple& getParentTuple(TItem* mItemPtr)
{
// <static assert that the tuple item types are unique>
// ...?
}
int main()
{
FruitTuple ft;
// I know these pointers point to objects inside a `FruitTuple`...
Apple* ptrApple{&std::get<0>(ft)};
Banana* ptrBanana{&std::get<1>(ft)};
Peach* ptrPeach{&std::get<2>(ft)};
// ...is there a way to get the `FruitTuple` they belong to?
auto& ftFromA(getParentTuple<FruitTuple>(ptrApple));
auto& ftFromB(getParentTuple<FruitTuple>(ptrBanana));
auto& ftFromP(getParentTuple<FruitTuple>(ptrPeach));
assert(&ftFromA == &ftFromB);
assert(&ftFromB == &ftFromP);
assert(&ftFromA == &ftFromP);
return 0;
}
如何以符合标准且不依赖于架构的方式实现getParentTuple<TTuple, TItem>
?
不可能。
编辑:
我认为标准中没有任何内容可以阻止兼容的元组实现在堆上单独分配元素。
然后,元素的内存位置将不允许任何导致元组对象位置的推理。
您唯一能做的是扩展元素类,使其还包含指向元组的后退指针,然后在将元素放入元组中后填充该指针。
以下是应该适用于常见实现的代码,但我很确定它不符合标准,因为它假设元组的内存布局是确定的。
在评论中,你说你不关心那个案子,所以你来了:
template<typename TTuple, typename TItem>
TTuple& getParentTuple(TItem* mItemPtr)
{
TTuple dummyTuple;
// The std::get by type will not compile if types are duplicated, so
// you do not need a static_assert.
auto dummyElement = (uintptr_t)&std::get<TItem>(dummyTuple);
// Calculate the offset of the element to the tuple base address.
auto offset = dummyElement - (uintptr_t)&dummyTuple;
// Subtract that offset from the passed element pointer.
return *(TTuple*)((uintptr_t)mItemPtr - offset);
}
请注意,这会构造元组一次,在某些情况下可能会产生不必要的副作用或性能影响。我不确定是否有编译时变体。
相关文章:
- 在 std::tuple 上使用 std::variant 的问题
- 在构造函数中使用可变参数初始化 std::tuple
- 转发复制的 std::tuple
- 我可以将新的 std::tuple 放入内存映射区域,并在以后读回吗?
- std::tuple 可以根据其值在编译时/运行时排序吗?
- 返回 std::tuple 中的引用和值
- 带有引用的std::tuple在clang中编译失败,但在gcc中编译失败
- 尝试实现std::tie和std::tuple的小版本
- std::tuple默认构造函数,带有move可构造元素
- 来自带有 std::tuple 的地图
- 如何从 std::async 任务返回 std::tuple
- 为什么 std::when_any 使用 std::tuple 而不是 std::vector 作为其结果类型?
- 为什么 std::integral_constant 在爆炸 std::tuple 时是必需的?
- 如何在std :: tuple中的每个元素上应用constexpr函数
- 如果创建支持返回可变参数类型列表的通用模板 API,我应该使用 std::tuple 还是其他东西?
- 类型安全 - all_of/ any_of/ none_of for std::tuple
- 将__m128i值转换为 std::tuple
- 使结构的行为类似于 std::tuple
- std::tuple faster than std::array?
- C++ 在标准::unordered_map中设置 std::tuple 值