C++之std::initializer_list的使用小結(jié)
1.引言
std::initializer_list 是 C++11 中的一個特性,它允許你使用花括號 {} 中的值列表來初始化容器或數(shù)組。通常用于初始化標(biāo)準(zhǔn)庫容器,比如 std::list、std::vector、std::set、std::map 以及數(shù)組, 也可以用于包含容器成員的自定義類。
std::initializer_list可以作用于可變數(shù)量的實參:有時我們無法提前預(yù)知應(yīng)該向函數(shù)傳遞幾個實參。為了編寫能處理不同數(shù)量實參的函數(shù),C++11新標(biāo)準(zhǔn)提供了兩種主要的方法:如果所有的實參類型相同,可以傳遞一個名為std::initializer_list的標(biāo)準(zhǔn)庫類型;如果實參的類型不同,我們可以編寫一種特殊的函數(shù),也就是所謂的可變參數(shù)模板。
2.std::initializer_list的實現(xiàn)原理
先看一下它的實現(xiàn):
template <class _Elem>
class initializer_list {
public:
using value_type = _Elem;
using reference = const _Elem&;
using const_reference = const _Elem&;
using size_type = size_t;
using iterator = const _Elem*;
using const_iterator = const _Elem*;
constexpr initializer_list() noexcept : _First(nullptr), _Last(nullptr) {}
constexpr initializer_list(const _Elem* _First_arg, const _Elem* _Last_arg) noexcept
: _First(_First_arg), _Last(_Last_arg) {}
_NODISCARD constexpr const _Elem* begin() const noexcept {
return _First;
}
_NODISCARD constexpr const _Elem* end() const noexcept {
return _Last;
}
_NODISCARD constexpr size_t size() const noexcept {
return static_cast<size_t>(_Last - _First);
}
private:
const _Elem* _First;
const _Elem* _Last;
};
// FUNCTION TEMPLATE begin
template <class _Elem>
_NODISCARD constexpr const _Elem* begin(initializer_list<_Elem> _Ilist) noexcept {
return _Ilist.begin();
}
// FUNCTION TEMPLATE end
template <class _Elem>
_NODISCARD constexpr const _Elem* end(initializer_list<_Elem> _Ilist) noexcept {
return _Ilist.end();
}從中可以明白:
1)std::initializer_list提供的迭代器都是const _Elem*,因此它不能修改參數(shù)的值的。
using iterator = const _Elem*; using const_iterator = const _Elem*;
2)當(dāng)使用花括號初始化語法時,編譯器會生成一個 std::initializer_list 對象。這個對象內(nèi)部實際上包含兩個指針:一個指向數(shù)組(或類似數(shù)組的結(jié)構(gòu))的開始位置,另一個指向結(jié)束位置(即下一個元素的起始位置,但不包括該位置)。
3)由于只存儲了兩個指針,std::initializer_list 的大小相對固定,通常是兩個指針的大小,與它所包含的元素的數(shù)量無關(guān)。
4)std::initializer_list 對象的生命周期是與其所在的函數(shù)或表達(dá)式相綁定的。這意味著,一旦離開了初始化列表所在的上下文(如函數(shù)參數(shù)傳遞、容器初始化等),std::initializer_list 對象就會失效,其指向的數(shù)據(jù)也可能不再有效。
5)std::initializer_list內(nèi)部不存儲對象,可以認(rèn)為它只是實際對象的一個視圖。因此,通常不建議將 std::initializer_list 作為類的成員變量存儲,因為它不能長期持有數(shù)據(jù)。
6)它擁有容器部分的特性:迭代器;因此它廣泛用于一些容器和數(shù)組。
7)std::initializer_list特化了std::begin()和std::end(),使得它的應(yīng)用場景更加廣泛。
8)它也常用于函數(shù)參數(shù),特別是當(dāng)函數(shù)需要處理多個同類型參數(shù)時,使用 std::initializer_list 可以使函數(shù)接口更加簡潔和靈活。
3.容器的初始化
使用std::initializer_list可以方便地初始化STL容器。在STL的很多容器都支持用std::initializer_list來構(gòu)造,包括 std::list、std::vector、std::set、std::map等,如:
std::vector的構(gòu)造函數(shù):
_CONSTEXPR20_CONTAINER vector(initializer_list<_Ty> _Ilist, const _Alloc& _Al = _Alloc())
: _Mypair(_One_then_variadic_args_t{}, _Al) {
auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Getal());
_Container_proxy_ptr<_Alty> _Proxy(_Alproxy, _Mypair._Myval2);
_Range_construct_or_tidy(_Ilist.begin(), _Ilist.end(), random_access_iterator_tag{});
_Proxy._Release();
}std::list的構(gòu)造函數(shù):
list(initializer_list<_Ty> _Ilist) : _Mypair(_Zero_then_variadic_args_t{})
{
_Construct_range_unchecked(_Ilist.begin(), _Ilist.end());
}std::map的構(gòu)造函數(shù):
map(initializer_list<value_type> _Ilist) : _Mybase(key_compare())
{
insert(_Ilist);
}std::set的構(gòu)造函數(shù):
set(initializer_list<value_type> _Ilist) : _Mybase(key_compare())
{
this->insert(_Ilist);
}等等,示例如下:
std::vector<int> a = {13, 32, 43, 54, 56};
std::set<int> b= {1, 2, 33, 4, 5, 2};
std::map<int, char> c= {{13, a}, {24, b}, {3666, c}};4.函數(shù)中使用std::initializer_list
可以將 std::initializer_list 用作函數(shù)的參數(shù),以便在函數(shù)調(diào)用時傳遞一組值。例如:
void func(std::initializer_list<int> values) {
// 使用初始化列表中的值
for (const auto& value : values) {
// 處理每個值
}
}
// 調(diào)用函數(shù)
func({13, 24, 35, 34, 52});
5.自定義類型中使用std::initializer_list
類的構(gòu)造函數(shù)可以接受 std::initializer_list 參數(shù),以便在創(chuàng)建對象時使用初始化列表進(jìn)行初始化。例如:
class MyContainer {
public:
MyContainer(std::initializer_list<int> list) : data(list) {
std::cout << "MyContainer initialized with " << data.size() << " elements." << std::endl;
}
private:
std::vector<int> data;
};
MyContainer c = {1, 2, 3, 4};6.迭代std::initializer_list
可以使用范圍基于的for循環(huán)或迭代器來遍歷std::initializer_list。例如:
std::initializer_list<int> list = {1, 2, 3, 4};
for (int n : list) {
std::cout << n << " ";
}
std::cout << std::endl;
for (auto it = list.begin(); it != list.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;7. 在模板中使用std::initializer_list
std::initializer_list在模板編程中也很有用,允許創(chuàng)建接受不定數(shù)量參數(shù)的泛型函數(shù)或類。例如:
template<typename T>
void printAll(std::initializer_list<T> list) {
for (const auto& item : list) {
std::cout << item << " ";
}
std::cout << std::endl;
}
printAll({1, 2, 3, 4});
printAll({"1241", "23525", "3252352"});8.std::initializer_list的限制
1) std::initializer_list只能存儲相同類型的元素。
2) std::initializer_list內(nèi)的元素不能被修改(它們是常量)。
std::initializer_list<int> list = {1, 2, 3, 4};
// list[0] = 10; // 錯誤:不能修改initializer_list中的元素9.總結(jié)
從上面可以看到,使用std::initializer_list的優(yōu)點:
1) 靈活性和擴展性:std::initializer_list可以用在任何需要可變數(shù)量參數(shù)的函數(shù)中,提供了高度的靈活性和擴展性。例如,你可以寫一個接受std::initializer_list 參數(shù)的函數(shù),讓它可以接受任意數(shù)量的元素進(jìn)行初始化。
2) 比 std::vector 更輕量和高效: 當(dāng)你使用std::initializer_list作為形參時,在值傳遞過程中,只包括一個指向初始化列表元素的指針和一個表示元素數(shù)量的整數(shù)。
參考:
std::initializer_list - cppreference.com
到此這篇關(guān)于C++之std::initializer_list的使用小結(jié)的文章就介紹到這了,更多相關(guān)C++ std::initializer_list內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語言生成隨機數(shù)以及設(shè)置隨機數(shù)范圍的方法(超詳細(xì))
文章介紹了C語言中生成隨機數(shù)的方法,包括使用`rand`和`srand`函數(shù),以及如何通過`time`函數(shù)設(shè)置隨機種子以確保每次運行程序生成的隨機數(shù)序列不同,此外,還詳細(xì)講解了如何根據(jù)需要設(shè)置隨機數(shù)的范圍,需要的朋友可以參考下2025-02-02
C語言使用isupper函數(shù)判斷字符是否為大寫字母的方法
在C語言編程中,字符處理是非常基礎(chǔ)的操作,尤其是判斷字符的大小寫狀態(tài),isupper 函數(shù)就是專門用于判斷一個字符是否為大寫英文字母的標(biāo)準(zhǔn)庫函數(shù),本篇博客將帶你全面掌握 isupper 函數(shù)的用法、原理、注意事項,搭配實戰(zhàn)案例,需要的朋友可以參考下2026-06-06
C和C++中實現(xiàn)對數(shù)據(jù)的流加密RC4算法
文章介紹了RC4流密碼算法,涵蓋其概述、特點(高效、簡單、適用性廣)、原理(密鑰流生成與異或加密)、初始化步驟及C/C++實現(xiàn)代碼,強調(diào)實際應(yīng)用需加強安全性,如密鑰管理與復(fù)雜加密庫的使用2025-10-10
基于Matlab實現(xiàn)離散系統(tǒng)分岔圖的繪制
這篇文章主要介紹了如何利用Matlab實現(xiàn)離散分岔圖的繪制,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)Matlab有一定的幫助,需要的可以參考一下2022-04-04
C語言實現(xiàn)字符串轉(zhuǎn)浮點函數(shù)的示例
字符串不僅可以轉(zhuǎn)換為整數(shù),也可以轉(zhuǎn)換為浮點數(shù),本文主要介紹了C語言實現(xiàn)字符串轉(zhuǎn)浮點函數(shù)的示例,具有一定的參考價值,感興趣的可以了解一下2022-02-02
C語言數(shù)據(jù)結(jié)構(gòu)不掛科指南之隊列詳解
這篇博客主要介紹一下隊列的概念,并且采用 C 語言,編寫兩種存儲實現(xiàn)方式:順序存儲和鏈?zhǔn)酱鎯?,?dāng)然還有常規(guī)的隊列基本操作的實現(xiàn)算法2022-09-09

