引入的目的或者主要用處
-
如果我們的函數無法事先知道函數要傳入的參數是多少,是什么類型,即要定義未知數量,未知類型的形參,要怎么定義呢,
一般是用省略號形參來定義,如:printf(char *format...)
c++11為我們再提供兩種主要的方法:- 可變參數模板,它和省略號差不多,但還有更加強大的用處
- 如果傳入的參數類型相同,但是數量不定的話,那就是我們的initializer_list了
-
變量或者對象的定義常用的大括號,中掛號,賦值符號
Rect r1 = {3, 7, 20, 50};
Rect r2{3, 7, 20, 50};
int a[6] = {0, 1, 2, 0, 1, 2};c++11提出了Unifrom Initialization(一致性初始化)的概念,也就是初始化可以都用一樣的形式,大括號的內容就是initializer_list
double b{9.9}
int values[] v{0, 1, 2, 0, 1, 2};
vectorcities{"beijing", "shanghai"};
initializer_list的定義和使用
這個是一個標准庫模板類,它內部使用的是array,比較簡單
需要注意的是
1.拷貝或者復制是淺拷貝,兩個對象共享元素
2.對象中的元素永遠是const,我們無法改變內部的值
- 對於參數數量不定的舉個代碼:
#include <iostream>
#include <initializer_list>
using namespace std;
void error_msg(int ErrCode, initializer_list<string> il)
{
cout << "errno(" << ErrCode << "): ";
for (auto beg = il.begin(); beg != il.end(); ++beg)
cout << *beg << " " ;
cout << endl;
}
int main()
{
error_msg(2, {"ENOENT", "No such file or directory!"});
}
運行結果:
- 一致性初始化
初始化是編譯器做的工作,比如定義變量complex<double> c{5.6, 6.7}
,編譯器會生成initializer_list< double >,調用構造函數時編譯器會分解元素並
逐一傳遞給函數,當然如果構造函數就有用initializer_list做參數的,那就直接傳進去就可以,不需要分解
現在的stl標准庫都有這種構造,比如vector:
vector(initializer_list<value_type> __l, const allocator_type& __a = allocator_type())
那么可以像數組那樣定義而不用一個個append:
vector<int> a{1, 2, 3, 4, 5, 6, 7};
參考
- 侯捷老師的課程:b站侯捷c++11
- C++ Primer, Fifth Edition.pdf