【问题标题】:Concise initialization syntax for nested variants?嵌套变体的简洁初始化语法?
【发布时间】:2012-08-20 01:48:00
【问题描述】:

我正在使用一个小型 C++ JSON 库来帮助提高我生疏的 C++ 技能,但我无法理解初始化列表的某些行为。

该库的核心是一个变体类(名为“var”),它存储任何各种 JSON 数据类型(null、boolean、number、string、object、array)。

我们的目标是让var 尽可能接近 JavaScript 变量,因此会发生大量运算符重载。原始数据类型很容易处理...

var fee = "something";
var fie = 123.45;
var foe = false;

问题在于对象(映射)和数组(向量)。

为了获得接近 JavaScript 对象和数组文字语法的东西,我使用了初始化列表。它看起来像这样:

// in my headers
typedef var object[][2];
typedef var array[]; 

// in user code
var foo = (array){ 1, "b", true };
var bar = (object){ { "name", "Bob" }, { "age", 42 } };

这效果很好。问题在于嵌套列表。

var foo = (array){ 1, "b", (array){ 3.1, 3.2 } };

由于某种原因,我的变体类将嵌套的“数组”解释为布尔值,给出:

[1, "b", true]

代替:

[1, "b", [3.1, 3.2]]

如果我将内部列表显式转换为 var,它会起作用:

var foo = (array){ 1, "b", (var)(array){ 3.1, 3.2 } };

为什么在将内部列表转换为数组后必须将其显式转换为 var,以及如何避免这种额外的转换?据我所知,它应该隐式地将数组转换为我的 var 类,因为它使用的是 var 数组的构造函数:

template <size_t length>
var(const var(&start)[length]) {
  // internal stuff
  init();
  setFromArray(vector<var>(start, start + length));
}

似乎如果没有显式转换为 var,初始化列表在从数组转换为 var 的过程中会以某种方式转换为其他东西。我试图了解为什么会发生这种情况,以及如何避免它。


这是a gist 的完整源代码。让我知道是否应该添加与问题相关的任何内容。


更新

显然(foo){1, "two"} 实际上并没有强制转换初始化列表;这是一个完整的表达式,称为compound literal。似乎它只在 C 中可用,尽管 g++ 不会抱怨,除非你给它-pedantic

看来我的选择是:

  • 找到另一种官方支持的简洁初始化语法。
  • 使用复合文字并希望它们在其他编译器中也能工作。
  • 放弃对 C++
  • 不要提供简洁的初始化语法。

对第一个选项的任何帮助都是我目前正在寻找的答案。

宏是另一种最后的选择,我已经编写了一些可以完成这项工作的宏,但我不想使用它们。

【问题讨论】:

  • 如果没有var 的概要,几乎不可能理解发生了什么,至少在声明了哪些构造函数和转换运算符(如果有)方面是这样。
  • @LucDanton 添加了源链接。
  • 一般代码中的任何其他 cmets 也是受欢迎的,因为我真的不知道我在做什么。
  • 您是否尝试标记构造函数explicit
  • @MichałGórny 我不知道(甚至不知道explicit)。会试试的,谢谢。

标签: c++ casting initialization variant


【解决方案1】:

您需要使用 Boost 已经提供给您的设施。

typedef boost::optional<boost::make_recursive_variant<
    float, int, bool, //.. etc
    std::unordered_map<std::string, boost::optional<boost::recursive_variant_>>,
    std::vector<boost::recursive_variant_>
> JSONType;

他们可以轻松定义递归变体类型。

【讨论】:

  • 谢谢,但是正如我们在聊天中讨论的那样,这只是将我的变体替换为另一个变体,它并不能解决具有简洁初始化语法的问题(或者提高我对 C++ 的理解,真的)。
猜你喜欢
  • 2015-04-08
  • 1970-01-01
  • 2017-04-25
  • 2023-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多