天天看點

C++初始化清單初始化和值初始化對構造函數的選擇

#include<cstdio>
#include<iostream>
#include<cstdlib>
using namespace std;

struct Foo {
    //方式1
    template<class ...args>
    Foo(args... rest) {
        cout << "Moudle1" << endl;
        func(rest...);
    }
    template<class ...args>
    void func(int a ,args... rest) {
        cout << a ;
        func(rest...);
    }
    void func() {
        cout << endl;
    }
    //方式2
    Foo(int a, int b, int c, int d) {
        cout << "Moudle2" << endl;
        cout << a << b << c << d<<endl;
    }
    //方式3
    Foo(std::initializer_list<int> list) {
        cout << "Moudle3" << endl;
        for (auto i : list) {
            cout << i;
        }
        cout << endl;
    }
};
int main(void) {
    Foo a{,,,};//構造方式1
    Foo b(,,,);//構造方式2
    system("pause");
    return ;
}
           

這三個構造函數在使用初始化清單初始化時會産生歧義,是以需要知道存在不同的構造函數會産生哪些情況。

僅存在方式1、方式2時,兩種構造方式均可成功被調用。

僅存在方式3時,構造方式2報錯,因為

std::initializer_list

隻能接受

{...}

的變量。

當方式1、方式2共存時,由于重載了特定的構造函數,均調用方式2。

當方式1、方式3共存時,構造方式1選擇了方式3初始化,構造方式2選擇了方式1初始化,這與重載了接收

{...}

變量的構造函數有關。

當方式2、方式3共存時,構造方式1選擇了方式3初始化,構造方式2選擇了方式2初始化,這與重載了接收

{...}

變量的構造函數有關,且說明了有特定的重載函數則不會選擇模闆。

當三者共存時,構造方式1選擇了方式3初始化,構造方式2選擇了方式2初始化。

由此可得出結論,

Foo a{1,2,3,4}

事實上與

Foo a({1,2,3,4})

等價,其中

{1,2,3,4}

std::initializer_list<int>[4]

類型,且

{1,2,3,4}

在一定的情況下可以轉化為函數的參數。

c++

繼續閱讀