在下面的示例中,我使用boost::json.
當我列印回傳的型別時,boost::json::value它是 type object,正如預期的那樣。
然后,我有 2 個在各方面都相同的類,除了BraceInit我boost::json::value使用大括號初始化ParenInit初始化我的成員和使用括號初始化我的成員boost::json::value。
使用大括號初始化會導致 myobject被轉換為array大小為 1 的 ,包含我原來的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
這里發生了什么?
我的“大括號初始化”實際上沒有像我預期的那樣進行大括號初始化,而是創建一個std::initializer_list大小為 1 的大括號?
uj5u.com熱心網友回復:
從[class.base.init]/7
mem-initializer 中的 expression-list 或 braced-init-list 用于根據 11.6 的直接初始化規則初始化指定的子物件(或者,在委托建構式的情況下,完整的類物件)。
11.6 此處指的是[dcl.init],其中第 17 段規定:
初始化器的語意如下。目標型別是正在初始化的物件或參考的型別,源型別是初始化運算式的型別。如果初始化器不是單個(可能是帶括號的)運算式,則未定義源型別。
(17.1) — 如果初始值設定項是(無括號的)大括號初始化串列或 = 大括號初始化串列,則物件或參考是串列初始化的 (11.6.4)。
11.6.4 僅指[dcl.init.list].
所以,對我來說,這聽起來像是_jv{jv}呼叫建構式的初始化串列版本(如果存在),根據boost 檔案,它會生成一個陣列。
注意:C 17 草案 N4659 中的所有專案
您可以在此處查看簡化版本:https ://godbolt.org/z/9qrf3EooY
編輯:cppreference將其簡化為:
在以下情況下會自動構造 std::initializer_list 物件:
一個花括號初始化串列用于串列初始化一個物件,其中相應的建構式接受一個 std::initializer_list 引數
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/472140.html
上一篇:什么時候應該將特定類的靜態方法標記為私有而不是公共?
下一篇:通過函式指標間接完美轉發?
