boost::json::value 的大括号初始化将其从对象转换为数组

brace-inititialisation of boost::json::value converts it from an object to an array

在下面的示例中,我使用 boost::json.

解析了一个 json 对象

当我打印返回的 boost::json::value 类型时,它是 object 类型,正如预期的那样。

然后我有 2 个 类 除了在 BraceInit 我使用大括号初始化初始化我的成员 boost::json::value 和在 ParenInit 我初始化我的会员 boost::json::value 使用括号。

使用大括号初始化导致我的 object 被转换成大小为 1 的 array,包含我原来的 object.

#include <iostream>
#include <boost/json.hpp>

namespace json = boost::json;

void print_type(const json::value& jv)
{
    switch (jv.kind())
    {
        case json::kind::object: std::cout << "object\n"; break;
        case json::kind::array: std::cout << "array\n"; break;
        default: std::cout << "other\n"; break;
    }
};

struct BraceInit
{
    BraceInit(json::value jv)
        : _jv{jv}
    {
        print_type(_jv);
    }
    json::value _jv;
};

struct ParenInit
{
    ParenInit(json::value jv)
        : _jv(jv)
    {
        print_type(_jv);
    }

    json::value _jv;
};

int main()
{
    const std::string str = R"({ "foo": "bar" })";
    const json::value jv = json::parse(str);
    print_type(jv);

    BraceInit b(jv);
    ParenInit p(jv);
    return 0;
}

输出:

object
array
object

这里发生了什么?

我的“大括号初始化”实际上没有像我预期的那样进行大括号初始化,而是创建了一个大小为 1 的 std::initializer_list 吗?

来自[class.base.init]/7

The expression-list or braced-init-list in a mem-initializer is used to initialize the designated subobject (or, in the case of a delegating constructor, the complete class object) according to the initialization rules of 11.6 for direct-initialization.

11.6 此处指的是 [dcl.init],其中第 17 段指出:

The semantics of initializers are as follows. The destination type is the type of the object or reference being initialized and the source type is the type of the initializer expression. If the initializer is not a single (possibly parenthesized) expression, the source type is not defined.

(17.1) — If the initializer is a (non-parenthesized) braced-init-list or is = braced-init-list, the object or reference is list-initialized (11.6.4).

11.6.4 只是指 [dcl.init.list].

所以,对我来说,这听起来像是 _jv{jv} 调用构造函数的 initialization-list 版本(如果它存在),根据 boost documentation,它会生成一个数组。

注意:C++17 草案 N4659 中的所有项目

您可以在此处查看简化版本:https://godbolt.org/z/9qrf3EooY


编辑:cppreference 将其简化为:

A std::initializer_list object is automatically constructed when:

a braced-init-list is used to list-initialize an object, where the corresponding constructor accepts an std::initializer_list parameter