【问题标题】:Variable initialization { } vs =变量初始化 { } vs =
【发布时间】:2021-07-13 23:53:46
【问题描述】:

好的,我只是遇到了一个奇怪的问题。此示例需要 nlohmann json 库,但可能有人可以解释一下。

#include <nlohmann/json.hpp>
using JSON = nlohmann::json;

int main(int, char **) {
    JSON json { JSON::object() };
    json["foo"] = "bar";
}

相比:

#include <nlohmann/json.hpp>
using JSON = nlohmann::json;

int main(int, char **) {
    JSON json = JSON::object();
    json["foo"] = "bar";
}

第一个例子是这样做的:

terminate called after throwing an instance of 'nlohmann::detail::type_error'
  what():  [json.exception.type_error.305] cannot use operator[] with a string argument with array
Aborted (core dumped)

第二个运行良好。

唯一的区别是json 的初始化语法。失败的使用{} 表示法,成功的使用= 表示法。我认为在这种情况下,这两种语法是完全等价的。显然不是。

我正在使用:

$ g++ --version
g++ (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0

有人能解释一下这两种初始化类型的区别吗?显然,它们不是 100% 可互换的。

【问题讨论】:

  • 我猜,JSON 类有一个特殊的 ctor 重载,它采用 initializer_list。想想vector v(5); 之间的区别。和矢量 v{5};
  • @IgorR。正确:nlohmann.github.io/json/api/basic_json/basic_json(构造函数 #5)。它创建一个数组。
  • 不,这是故意的。 JSON json { JSON::object(), JSON::object(), JSON::object() }; 是“相同”的语法。单元素数组看起来很奇怪。这与写std::vector&lt;int&gt; x {3}; 是同一个“错误”
  • @JosephLarson - 这不是现代问题。从第一个发布的标准开始,各种与重载相关的怪物都是可能的。试着弄清楚std::string str("a", "b"); 做了什么。我们总是需要了解我们在做什么。
  • 对这个问题的幽默看法:imgur.com/3wlxtI0

标签: c++


【解决方案1】:

有人能解释一下这两种初始化类型的区别吗?显然,它们不是 100% 可互换的。

首先,这是正确的。有许多不同类型的初始化,而您在此处给出的两种并不等价。

但是,您编写它们的方式并不等同于 any 类型;

Type t = Type();

是使用默认构造函数进行初始化,而

Type t = Type { Type() };

要么通过复制构造函数进行初始化,或者,如果存在,构造函数采用std::initializer_list(在 C++11 中——在这种情况下从 C++17 开始将选择复制构造函数)。后者是这里的情况;您不是在复制对象,而是在创建一个新的 JSON 对象并通过 std::initializer_list&lt;JSON&gt; 将您的对象传递给它,nlohmann::JSON 将创建一个 JSON 数组。

【讨论】:

  • 好吧,复制构造函数在这两种情况下都会被调用。
  • 自 C++17 起没有。
  • @IgorR。我没有检查过,但只有在 JSON::object 返回的内容不是 JSON 类型时才会出现这种情况,否则副本将被忽略。
  • 你可能用C++17查过,但是这里没有这个标签。
  • @IgorR。 C++ 标签表示当前标准。现在是 C++20。
【解决方案2】:

第一个示例使用list initialization,第二个示例使用copy initialization

所以它们是不同的,两个链接提供了两种语法的完整描述。具体来说,如果您搜索复制初始化的效果是类型 T 的对象的列表初始化的效果是,比较这些列表会告诉您有什么区别。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-12
    • 1970-01-01
    • 2019-05-17
    • 2021-07-08
    • 2012-06-15
    • 2012-10-19
    • 2016-11-03
    相关资源
    最近更新 更多