c++ - 访问 std::variant 中的结构成员
问题描述
我有一个 std::variant,它有两个不同的结构作为替代。现在我需要用另一种选择的数据填充它(我在运行时知道),但它必须以某种方式,可以单独在结构中写入元素。显然,这是行不通的:
struct ContainerOne {
uint8_t x;
};
struct ContainerTwo {
uint8_t y;
uint8_t z;
};
std::variant<ContainerOne, ContainerTwo> ContainerCollection; // CHOICE
ContainerCollection.x = 20; // Error
还有另一种方法可以实现这一目标吗?如果我知道我想写的替代方案,也许一种方法可以告诉变体它具有哪种结构或类似的东西?
我能弄清楚的唯一方法是为变体的内存空间制作一个强制引用并使用它来写入它。问题是这没有使用变体的方法,因此不会自动设置索引。同样以相同的方式设置索引也很困难,因为索引的大小因不同的变体而异(有时是一个字节,有时是 8 个字节):
ContainerOne &ContainerOneRef = *(reinterpret_cast<ContainerOne*>(&ContainerCollection));
uint8_t* newptr = reinterpret_cast<uint8_t*>(&ContainerCollection) + sizeof(ContainerCollection) - 0x01; // jump to the end of variant and one byte back, in the case the index is 1 Byte
*newptr = 0x01;
ContainerOneRef.x = 20;
或者有没有办法找出索引的大小?
解决方案
您需要在运行时进行某种调度,以根据活动元素(成员函数index()
)的返回索引选择适当的值。例如,如果我们为每种类型提供选择并使用std::get
:
#include <iostream>
#include <cstdlib>
#include <variant>
struct ContainerOne {
uint8_t x;
};
struct ContainerTwo {
uint8_t y;
uint8_t z;
};
using ContainerType = std::variant<ContainerOne, ContainerTwo>;
void init_ContainerOne(ContainerType& v) {
std::get<ContainerOne>(v).x = 20;
std::cout << __PRETTY_FUNCTION__ << "\n";
}
void init_ContainerTwo(ContainerType& v) {
std::get<ContainerTwo>(v) = {};
std::cout << __PRETTY_FUNCTION__ << "\n";
}
decltype(&init_ContainerOne) dispatch[] = { init_ContainerOne, init_ContainerTwo };
int main()
{
std::variant<ContainerOne, ContainerTwo> container = ContainerOne{};
dispatch[container.index()](container);
}
C++17 提供std::visit让基础架构更易于构建
推荐阅读
- css - 在不使用 Material 的调色板颜色的情况下创建 Angular 主题
- clojure - 向量中的单个重复项
- python - python中的递归函数不会调用自己
- amazon-web-services - 我应该将 AWS 的哪些部分用于 Web 门户?
- javascript - 如何将 JavaScript 变量链接到 HTML 值?
- database - 在 Firestore 中更新值时没有字段错误
- wordpress - Wordpress 基本类别名称更改/仅针对一个类别的永久链接
- python - 在生产中调试 = False 时出现 500 服务器错误
- c# - 使用 LINQ 基于单个属性过滤 EntityCollection:
- regex - UltraEdit(或 MacOS 正则表达式):删除 xml 中的多行