c++ - 我可以将 braced-init-list 用于 std::variant 的 vector 吗?

标签 c++ initialization variant c++17

我有 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/

相关文章:

c++ - 在 C++ 中向文件添加换行符

objective-c - 初始化 Objective-C 属性的最佳实践

c++ - 非递归访问自定义变量-如何优雅地返回值?

c++ - 遗留项目中的重复代码删除策略

c++ - 调用默认构造函数时模板可变参数编译错误

c++ - 编译错误: “lvalue required as left operand of assignment” Unsure why

c++ - 如何创建一个html树?

delphi - 为什么大多数 Delphi 示例使用 FillChar() 来初始化记录?

c++ - p。上缺少成员初始化程序列表的示例。 184《使用C++进行编程的原理和实践》,第二版

c++ - 是否有具有多访问方法的可变参数模板变体?