![](/img/trans.png)
[英]List-initialization and failed overload resolution of initializer_list constructor
[英]initializer_list and default constructor overload resolution
#include <initializer_list>
#include <iostream>
using namespace std;
struct Y {};
struct X
{
X(initializer_list<Y>) { cout << "yay" << endl; }
explicit X() { cout << "boo" << endl; }
};
X f()
{
return {};
}
int main()
{
f();
return 0;
}
這打印出“噓聲”。 為什么不打印出“yay”?
無論如何要區分以下兩種結構:
X()
X{}
要么
return X();
return {};
要么
void g(const X&)
g(X())
g({})
謝謝。
無論如何要區分以下兩種結構:
不,它們不是不同的結構。
{}構造函數語法的主要目的是引入統一初始化,使初始化工作在任何地方都相同。 如果他們之間存在差異,那就不一致了。
如果要使用空初始化列表構造函數,則必須聲明您正在顯式傳遞初始化列表。 像這樣: return initializer_list<Y>{};
當然,統一初始化的另一個目的是不必輸入類型名稱,所以你可以通過return {{}};
獲得相同的效果return {{}};
return {};
如果有的話,將始終使用默認構造函數。
return X({});
或者return {{}};
將從一個空的初始化列表構造。
它使用默認構造函數,因為使用{}
列表初始化意味着始終是一種簡短的值初始化形式,忽略其他構造函數,即使它們是初始化列表構造函數。
無論如何要區分以下兩種結構:......
X()
始終是值初始化,而X{}
只是值初始化,如果X
有默認構造函數。 如果它是聚合,則X{}
是聚合初始化(遞歸地初始化X
的成員{}
)。 如果它只有初始化列表構造函數而沒有默認構造函數,則X()
無效且X{}
可能有效
struct A { A(initializer_list<int>); };
A a = A{}; // valid
A b = A(); // invalid
從本質上講, X{}
作用取決於X
是什么。 但是X()
總是初始化值。
...或返回X(); vs return {};
一些微妙的提及......在return {}
,目標是copy-list-initialized,而在return X();
首先直接初始化一個X
但即使它是copy-list-initialized,它也可以使用explicit
默認構造函數,因為值初始化並不關心explicit
。 但是,當您return {}
並嘗試使用顯式非默認構造函數時,您將出錯
struct A {
explicit A(initializer_list<int>);
};
A f() { return {}; } // error!
struct B {
explicit B();
};
B g() { return {}; } // OK
你可以更明確一點:
return initializer_list<Y>();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.