簡體   English   中英

C++:通過花括號調用構造函數?

[英]c++ : calling constructors via curly braces?

class A 
{
    int value_;
    public:
    A(int value):value_(value){}
};

A get_a1(int value)
{
    return A(value);
}

A get_a2(int value)
{
    return {value};
}


int main()
{
    A a1 = get_a1(1);
    A a2 = get_a2(2);
}

get_a1()get_a2()之間有什么區別get_a2()如果有)?

return {value};如何return {value}; 叫? (我猜“通過花括號調用構造函數”不是指代這個的正確方法)

在你的情況下,根本沒有區別。 但是如果你稍微修改一下你的代碼,就會有明顯的不同!

首先,你可以用不同的方式構造你的類型,所有描述在這里:初始化

不同之處在於,如果您的類還提供了一個采用std::initializer_list的構造std::initializer_list

請參閱以下修改/擴展的代碼以顯示差異:

class A 
{   
    public:
        A(int value):value_(value){ std::cout << "int" << std::endl;}
        A(const std::initializer_list<int>& ){ std::cout << "list" << std::endl;}
        void print()
        {   
            std::cout << value_ << std::endl;
        }   
    private:
        int value_;
};  

A get_a1(int value)
{   
    std::cout << "()" << std::endl;
    return A(value);
}   

A get_a2(int value)
{
    std::cout << "{}" << std::endl;
    return {value};
}


int main()
{   
    A a1 = get_a1(1);
    a1.print();
    A a2 = get_a2(2);
    a2.print();
}   

如果您運行該程序,您將看到使用{}將使用std::initializer_list調用構造函數,而使用()將使用您的int構造函數。

為什么在標准中描述:

§13.3.1.7 [over.match.list]/p1:

當非聚合類類型T被列表初始化 (8.5.4) 時,重載決議分兩個階段選擇構造函數:

  • 最初,候選函數是類T的初始化列表構造函數(8.5.4),參數列表由初始化列表作為單個參數組成。
  • 如果找不到可行的初始化列表構造函數,則再次執行重載決議,其中候選函數是類T所有構造函數,參數列表由初始化列表的元素組成。

如果初始值設定項列表沒有元素並且T具有默認構造函數,則省略第一階段。 在復制列表初始化中,如果選擇了explicit構造函數,則初始化是格式錯誤的。

此外,初始化列表構造函數不允許縮小!

§8.5.4 列表初始化

(3.4) 否則,如果 T 是類類型,則考慮構造函數。 枚舉適用的構造函數,並通過重載決議([over.match]、[over.match.list])選擇最佳構造函數。 如果需要縮小轉換(見下文)來轉換任何參數,則程序格式錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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