簡體   English   中英

initializer_list和默認構造函數重載決策

[英]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”?

無論如何要區分以下兩種結構:

  1. X()
  2. X{}

要么

  1. return X();
  2. return {};

要么

void g(const X&)
  1. g(X())
  2. 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM