我有 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;
一切正常,直到我尝试使用 braced-init-lists 来填充 vector 。
换句话说,这是有效的:
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>)
我不明白为什么会这样。在这种情况下我不能使用大括号初始化吗?如果是这样,……为什么?或者我是否需要以某种方式修改我的结构以支持这种初始化?
Here是 wandbox.org 上的一个最小工作示例,可进一步说明我的问题。
最佳答案
Can't I use brace initialization in this case? If so,... why? Or do I need to modify my structs in some way that they support this kind of initialization?
不,你不能。不,你无法做出任何改变来让它发挥作用。这是一个真正简化的示例:
template <typename T> void foo(T&& );
foo({1}); // what is T?
Braced-init-lists 没有类型,因此无法推导它们。 variant
的方式的构造函数的工作原理是推导其参数,然后选择最佳替代方案从中进行初始化。它不能从你的 braced-init-list 做到这一点,你必须使用具有类型的表达式。
唯一可行的方法是 variant<A, B, C>
本身有非模板构造函数variant(A&& )
, variant(B&& )
, 和 variant(C&& )
. 那么,braced-init-lists 就可以工作了。
关于c++ - 我可以将 braced-init-list 用于 std::variant 的 vector 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48813049/