i有2个结构,这些结构容纳不同的数据,每个构造都可以将此数据序列化为JSON字符串:
struct Struct1
{
Struct1(int value) : value(value){};
int value;
std::string ToJSON() const
{
std::string ret = "{value: " + std::to_string(value) + "}";
return ret;
}
};
struct Struct2
{
Struct2(std::string id, std::string image, std::string name) : id(id), image(image), name(name){};
std::string id;
std::string image;
std::string name;
std::string ToJSON() const
{
return "{id: " + id + " image: " + image + " name: " + name + "}";
}
};
我需要将其中的几个存储在一个容器中,以便以后在它们上迭代并从每个对象中获取JSON字符串。我使用std::variant
这样做。
std::vector<std::variant<Struct1, Struct2>> v3;
我可以像这样迭代容器:
auto GetJSONString = [](auto&& _in){return _in.ToJSON();};
for (const auto& nextV : v3)
{
auto test = std::visit(GetJSONString, nextV);
std::cout << test << " ";
}
std::cout << std::endl;
一切正常工作,直到我尝试使用Brad-Init lists填充向量。
换句话说,这在起作用:
std::vector<std::variant<Struct1, Struct2>> v{Struct1(5), Struct2("someid", "someimage", "somename")};
但这不是:
std::vector<std::variant<Struct1, Struct2>> v4{ {13}, {"someid", "someimage", "somename"}};
在不工作代码上,我会收到以下编译器错误:
error: no matching function for call to 'std::vector<std::variant<Struct2, Struct1> >::vector(<brace-enclosed initializer list>)
我不明白这是为什么。在这种情况下,我不能使用支撑初始化吗?如果是这样,...为什么?还是我需要以某种方式修改我的结构以支持这种初始化?
这是wandbox.org上的最小工作示例,以进一步说明我的问题。
在这种情况下,我不能使用支架初始化吗?如果是这样,...为什么?还是我需要以某种方式修改我的结构以支持这种初始化?
不,你不能。不,您无法做出任何改变以使其正常工作。这是一个非常简单的示例:
template <typename T> void foo(T&& );
foo({1}); // what is T?
支撑列表没有类型,因此不能推导它们。variant
的构造函数的工作方式是推论其参数,然后选择最佳替代品以初始化。它不能从您的支撑列表中做到这一点,您必须使用具有类型的表达式。
唯一可以使工作的方法是variant<A, B, C>
本身具有 non-Template 构造函数variant(A&& )
,variant(B&& )
和variant(C&& )
。然后,,支撑式列表将起作用。
您打算致电的variant
构造函数是
template<typename T>
constexpr variant(T&& t)
但是该构造函数模板的模板参数扣除将失败,因为 braced-init-lists 没有类型。
使用将std::in_place_type_t<T>
作为第一个参数
std::vector<std::variant<Struct2, Struct1>> v4{
{ std::in_place_type<Struct1>, 13 },
{ std::in_place_type<Struct2>, "someid", "someimage", "somename" }
};
,但这也失败了,因为所讨论的variant
构造函数是explicit
,该构建器不适合用于复制列表initialization。
所以您列出的选项是最好的
std::vector<std::variant<Struct2, Struct1>> v4{
Struct1{ 13 },
Struct2{ "someid", "someimage", "somename" }
};