nitializer\_list是C++11提供的新類型,定義在頭文件中。
用于表示某種特定類型的值的數組,和vector一樣,initializer\_list也是一種模板類型。
```
template< class T >
class initializer_list;
```
## 列表初始化
C++11擴大了初始化列表的適用范圍,使其可用于所有內置類型和用戶定義的類型。無論是初始化對象還是某些時候為對象賦新值,都可以使用這樣一組由花括號括起來的初始值了。使用初始化列表時,可添加=,也可不添加。
```
//定義一個變量并初始化
int units_sold=0;
int units_sold(0);
int units_sold={0}; //列表初始化
int units_sold{0}; //列表初始化
```
當初始化列表用于內置類型的變量時,這種初始化形式有一個重要特點:如果我們使用列表初始化值存在丟失信息的風險,則編譯器將報錯:
~~~
long double ld=3.1415926536;
int a={ld},b={ld}; //錯誤:轉換未執行,因為存在丟失信息的風險
int c(ld),d=ld; //正確:轉換執行,且確實丟失了部分值
~~~
## initializer\_list的使用
它提供的操作如下:
~~~
initializer_list<T> lst;
//默認初始化;T類型元素的空列表
initializer_list<T> lst{a,b,c...};
//lst的元素數量和初始值一樣多;lst的元素是對應初始值的副本
lst2(lst)
lst2=lst
//拷貝或賦值一個initializer_list對象不會拷貝列表中的元素;拷貝后,原始列表和副本元素共享
lst.size() //列表中的元素數量
lst.begin() //返回指向lst中首元素的指針
lst.end() //返回指向lst中尾元素下一位置的指針
~~~
需要注意的是,initializer\_list對象中的元素永遠是常量值,我們無法改變initializer\_list對象中元素的值。并且,拷貝或賦值一個initializer\_list對象不會拷貝列表中的元素,其實只是引用而已,原始列表和副本共享元素。
和使用vector一樣,我們也可以使用迭代器訪問initializer\_list里的元素
~~~
void error_msg(initializer_list<string> il)
{
for(auto beg=il.begin();beg!=il.end();++beg)
cout<<*beg<<" ";
cout<<endl;
}
~~~
如果想向initializer\_list形參中傳遞一個值的序列,則必須把序列放在一對花括號內:
~~~
//expected和actual是string對象
if(expected != actual)
error_msg({"functionX",expectde,actual});
else
error_msg({"functionX","okay"});
~~~
說了這么多,那initializer\_list到底有什么應用呢?
有了initializer\_list之后,對于STL的container的初始化就方便多了,比如以前初始化一個vector需要這樣:
~~~
std::vector v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
~~~
而現在c++11添加了initializer\_list后,我們可以這樣初始化
~~~
std::vector v = { 1, 2, 3, 4 };
~~~
并且,C++11允許構造函數和其他函數把初始化列表當做參數。
~~~
#include <iostream>
#include <vector>
class MyNumber
{
public:
MyNumber(const std::initializer_list<int> &v) {
for (auto itm : v) {
mVec.push_back(itm);
}
}
void print() {
for (auto itm : mVec) {
std::cout << itm << " ";
}
}
private:
std::vector<int> mVec;
};
int main()
{
MyNumber m = { 1, 2, 3, 4 };
m.print(); // 1 2 3 4
return 0;
}
~~~
- C++基礎
- 什么是 POD 數據類型?
- 面向對象三大特性五大原則
- 低耦合高內聚
- C++類型轉換
- c++仿函數
- C++仿函數了解一下?
- C++對象內存模型
- C++11新特性
- 智能指針
- 動手實現C++的智能指針
- C++ 智能指針 shared_ptr 詳解與示例
- 現代 C++:一文讀懂智能指針
- Lamda
- c++11多線程
- std::thread
- std::async
- std::promise
- std::future
- C++11 的內存模型
- 初始化列表
- std::bind
- std::tuple
- auto自動類型推導
- 可變參數模板
- 右值引用與移動語義
- 完美轉發
- 基于范圍的for循環
- C++11之POD類型
- std::enable_if
- C++14/17
- C++20
- 協成
- 模塊
- Ranges
- Boost
- boost::circular_buffer
- 使用Boost.Asio編寫通信程序
- Boost.Asio C++ 網絡編程
- 模板
- 模板特化/偏特化
- C++模板、類模板、函數模板詳解都在這里了
- 泛化之美--C++11可變模版參數的妙用
- 模板元編程
- 這是我見過最好的模板元編程文章!