C++11中std::initializer_list的使用
initializer_list是一種標(biāo)準(zhǔn)庫類型,用于表示某種特定類型的值的數(shù)組。和vector一樣,initializer_list也是一種模板類型,定義initializer_list對象時,必須說明列表中所含元素的類型。和vector不一樣的是,initializer_list對象中的元素永遠(yuǎn)是常量值,我們無法改變initializer_list對象中元素的值。
initializer_list可以作用于可變數(shù)量的實(shí)參:有時我們無法提前預(yù)知應(yīng)該向函數(shù)傳遞幾個實(shí)參。為了編寫能處理不同數(shù)量實(shí)參的函數(shù),C++11新標(biāo)準(zhǔn)提供了兩種主要的方法:如果所有的實(shí)參類型相同,可以傳遞一個名為initializer_list的標(biāo)準(zhǔn)庫類型;如果實(shí)參的類型不同,我們可以編寫一種特殊的函數(shù),也就是所謂的可變參數(shù)模板。
作用于initializer_list對象的begin和end操作類似于vector對應(yīng)的成員。begin()成員提供一個指向列表首元素的指針,end()成員提供一個指向列表尾元素的指針。
含有initializer_list形參的函數(shù)也可以同時擁有其他形參。
類模板initializer_list用于訪問初始化列表(initialization list),列表元素的數(shù)據(jù)類型為const T.編譯器從花括號(brace)封閉的、元素由逗號分隔開的初始化列表自動構(gòu)造initializer_list模板類, 例如:
auto il = {10,20, 30}; // the type of il is an initializer_list<int>
類模板initializer_list引用(refer to)但不包含這個這個列表的元素。復(fù)制這個initializer_list對象將引用到同一個基礎(chǔ)列表而不是引用到基礎(chǔ)列表的新的拷貝。std::initializer_list并不是一個容器,不要用它傳遞期望長期存儲的值。構(gòu)造函數(shù)的形參如果為一個initializer_list模板類,則這種特殊的構(gòu)造函數(shù)稱為初始化器列表構(gòu)造函數(shù)(initializer_list constructor),例如:
struct myclass {myclass (int,int);myclass (initializer_list<int>);/* definitions ... */
};
myclass foo {10,20}; // calls initializer_list constructor
myclass bar (10,20); // calls first constructor
僅可以從braced-init-list推導(dǎo)出initializer_list<T>。這一過程中,編譯器自動查詢哪些構(gòu)造函數(shù)可以用initializer_list<T>作為參數(shù),并據(jù)此確定initializer_list的模板參數(shù)T的類型,從而對braced-init-list做類型轉(zhuǎn)換。
C++11標(biāo)準(zhǔn)明確規(guī)定不能由模板參數(shù)推導(dǎo)出對應(yīng)實(shí)參std::initializer_list的類型。
C++還有一種特殊的形參類型(即省略符),可以用它傳遞可變數(shù)量的實(shí)參。
省略符形參是為了便于C++程序訪問某些特殊的C代碼而設(shè)置的,這些代碼使用了名為varargs的C標(biāo)準(zhǔn)庫功能。通常,省略符形參不應(yīng)用于其他目的。省略符形參只能出現(xiàn)在形參列表的最后一個位置。
? std::initializer_list:This type is used to access the values in a C++ initialization list, which is a list of elements of type const T.
下面是從其它文章中copy的std::initializer_list測試代碼,詳細(xì)內(nèi)容介紹可以參考對應(yīng)的reference:
#include "initializer_list.hpp"
#include <initializer_list>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>///
// reference: http://www.cplusplus.com/reference/initializer_list/initializer_list/
struct myclass {std::string str;myclass(std::initializer_list<int> args) {std::stringstream ss;std::initializer_list<int>::iterator it; // same as: const int* itfor (it = args.begin(); it != args.end(); ++it) ss << ' ' << *it;str = ss.str();}
};template<class T>
struct simple_container {T * data;unsigned n;simple_container(std::initializer_list<int> args) {data = new T[args.size()];n = 0;for (T x : args) { data[n++] = x; }}T* begin() { return data; }T* end() { return data + n; }
};template<class T>
void print_list(std::initializer_list<T> il)
{for (const T* it = std::begin(il); it != std::end(il); ++it) std::cout << ' ' << *it;std::cout << '\n';
}int test_initializer_list_1()
{
{std::initializer_list<int> mylist;mylist = { 10, 20, 30 };std::cout << "mylist contains:";for (int x : mylist) std::cout << ' ' << x;std::cout << '\n';
}{myclass myobject{ 10, 20, 30 };std::cout << "myobject contains:" << myobject.str << '\n';
}{simple_container<int> myobject{ 10, 20, 30 };std::cout << "myobject contains:";for (int x : myobject) std::cout << ' ' << x;std::cout << '\n';
}{print_list({ 10, 20, 30 });
}{// 編譯器從花括號(brace)封閉的、元素由逗號分隔開的初始化列表自動構(gòu)造initializer_list模板類auto il = { 10, 20, 30 };for (auto i : il)std::cout << i << " ";std::cout << std::endl;
}return 0;
}// reference: http://en.cppreference.com/w/cpp/utility/initializer_list
template <class T>
struct S {std::vector<T> v;S(std::initializer_list<T> l) : v(l) {std::cout << "constructed with a " << l.size() << "-element list\n";}void append(std::initializer_list<T> l) {v.insert(v.end(), l.begin(), l.end());}std::pair<const T*, std::size_t> c_arr() const {return{ &v[0], v.size() }; // copy list-initialization in return statement// this is NOT a use of std::initializer_list}
};template <typename T>
void templated_fn(T) {}int test_initializer_list_2()
{S<int> s = { 1, 2, 3, 4, 5 }; // copy list-initializations.append({ 6, 7, 8 }); // list-initialization in function callstd::cout << "The vector size is now " << s.c_arr().second << " ints:\n";for (auto n : s.v)std::cout << n << ' ';std::cout << '\n';std::cout << "Range-for over brace-init-list: \n";for (int x : {-1, -2, -3}) // the rule for auto makes this ranged-for workstd::cout << x << ' ';std::cout << '\n';auto al = { 10, 11, 12 }; // special rule for autostd::cout << "The list bound to auto has size() = " << al.size() << '\n';// templated_fn({1, 2, 3}); // compiler error! "{1, 2, 3}" is not an expression,// it has no type, and so T cannot be deducedtemplated_fn<std::initializer_list<int>>({ 1, 2, 3 }); // OKtemplated_fn<std::vector<int>>({ 1, 2, 3 }); // also OKreturn 0;
}
GitHub:? https://github.com/fengbingchun/Messy_Test
總結(jié)
以上是生活随笔為你收集整理的C++11中std::initializer_list的使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 线性回归介绍及分别使用最小二乘法和梯度下
- 下一篇: C++/C++11中头文件numeric