#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}
在一定的情況下可以轉化為函數的參數。