欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++11中初始化列表initializer lists的使用方法

 更新時(shí)間:2021年09月25日 11:46:43   作者:lysuns  
C++11引入了初始化列表來初始化變量和對(duì)象,自定義類型,如果想用初始化列表就要包含initializer_list頭文件

C++11引入了初始化列表來初始化變量和對(duì)象。自定義類型,如果想用初始化列表就要包含initializer_list頭文件。

C++11將使用大括號(hào)的初始化(列表初始化)作為一種通用初始化方式,可用于所有類型。初始化列表不會(huì)進(jìn)行隱式轉(zhuǎn)換。

C++11提供的新類型,定義在<initializer_list>頭文件中。

template< class T >
class initializer_list;

先說它的用處吧,然后再詳細(xì)介紹一下。

首先有了initializer_list之后,對(duì)于STL的container的初始化就方便多了,比如以前初始化一個(gè)vector需要這樣:

int a[] = {0, 1, 2, 3};
std::vector<int> vec(a, a+sizeof(a));

或者

std::vector<int> vec;
vec.push_back(1);
vec.push_back(3);
vec.push_back(3);
vec.push_back(2);

有了initializer_list后,就可以直接像初始化數(shù)組一樣:

class Test {

private:
    static std::map<string, string> const nameToBirthday = {
        {"lisi", "18841011"},
        {"zhangsan", "18850123"},
        {"wangwu", "18870908"},
        {"zhaoliu", "18810316"},
    };
}

當(dāng)然啦,里面的std::map必須提供參數(shù)為initializer_list的構(gòu)造函數(shù)如:

map( std::initializer_list<value_type> init,
const Compare& comp = Compare(),
const Allocator& alloc = Allocator() );

其實(shí)for(initializer: list)中如果list是個(gè)形如:{a, b, c...},那么其實(shí)list自動(dòng)被構(gòu)造成了initializer_list對(duì)象。

下面稍微介紹一下initializer_list

一個(gè)initializer_list當(dāng)出現(xiàn)在以下兩種情況的被自動(dòng)構(gòu)造:

當(dāng)初始化的時(shí)候使用的是大括號(hào)初始化,被自動(dòng)構(gòu)造。包括函數(shù)調(diào)用時(shí)和賦值
當(dāng)涉及到for(initializer: list),list被自動(dòng)構(gòu)造成initializer_list對(duì)象
也就是說initializer_list對(duì)象只能用大括號(hào){}初始化。

拷貝一個(gè)initializer_list對(duì)象并不會(huì)拷貝里面的元素。其實(shí)只是引用而已。而且里面的元素全部都是const的。

下面一個(gè)例子可以幫助我們更好的理解如何使用initializer_list:

#include <iostream>
#include <vector>
#include <initializer_list>

using namespace std;

template <class T>
struct S {
    vector<T> v;
    S(initializer_list<T> l) : v(l){
        cout << "constructed with a " << l.size() << "-elements lists" << endl;
    }
    void append(std::initializer_list<T> l) {
        v.insert(v.end(), l.begin(), l.end());
    }

    pair<const T*, size_t> c_arr() const{
        return {&v[0], v.size()};
    }

};


template <typename T>
void templated_fn(T arg) {
    for (auto a : arg)
        cout << a << " ";
    cout << endl;
}

int main() {
    S<int> s = {1, 2, 3, 4, 5}; //automatically construct a initializer_list 
                                // object and copy it
    s.append({6, 7 , 8});         //list-initialization in function call

    cout << "The vector size is now " << s.c_arr().second << " ints:" << endl;

    for (auto n : s.v)
        cout << ' ' << n;
    cout << endl;

    cout << "range-for over brace-init-list: " << endl;
    
    for (auto x : {-1, -2, 03})   //// the rule for auto makes this ranged for work
        cout << x << " ";
    cout << endl;

    auto al = {10, 11, 12};  //special rule for auto

    cout << "The list bound to auto has size() = " << al.size() << endl;


    //templated_fn({1, 2, 3});   //compiler error! "{1, 2, 3}" is not an expressionit has no type, and so T cannot be duduced.

    templated_fn<initializer_list<int> > ({7, 8, 9}); //ok
    templated_fn<vector<int> >({3, 5, 7});           //also ok

    return 0;
}

下面是從其他文章中copy的測試代碼,詳細(xì)內(nèi)容介紹可以參考對(duì)應(yīng)的reference:

#include "init_list.hpp"
#include <iostream>
#include <vector>
#include <map>
#include <string>
#include <set>
 
///
// reference: http://en.cppreference.com/w/cpp/language/list_initialization
struct Foo {
	//std::vector<int> mem = { 1, 2, 3 }; // list-initialization of a non-static member
	//std::vector<int> mem2;
	//Foo() : mem2{ -1, -2, -3 } {} // list-initialization of a member in constructor
};
 
std::pair<std::string, std::string> f(std::pair<std::string, std::string> p)
{
	return{ p.second, p.first }; // list-initialization in return statement
}
 
int test_init_list1()
{
	int n0{};     // value-initialization (to zero)
	int n1{ 1 };    // direct-list-initialization
	std::string s1{ 'a', 'b', 'c', 'd' }; // initializer-list constructor call
	std::string s2{ s1, 2, 2 };           // regular constructor call
	std::string s3{ 0x61, 'a' }; // initializer-list ctor is preferred to (int, char)
 
	int n2 = { 1 }; // copy-list-initialization
	double d = double{ 1.2 }; // list-initialization of a temporary, then copy-init
 
	std::map<int, std::string> m = { // nested list-initialization
			{ 1, "a" },
			{ 2, { 'a', 'b', 'c' } },
			{ 3, s1 }
	};
 
	std::cout << f({ "hello", "world" }).first << '\n'; // list-initialization in function call
 
	const int(&ar)[2] = { 1, 2 }; // binds a lvalue reference to a temporary array
	int&& r1 = { 1 }; // binds a rvalue reference to a temporary int
	//  int& r2 = {2}; // error: cannot bind rvalue to a non-const lvalue ref
 
	//  int bad{1.0}; // error: narrowing conversion
	unsigned char uc1{ 10 }; // okay
	//  unsigned char uc2{-1}; // error: narrowing conversion
 
	Foo f;
 
	std::cout << n0 << ' ' << n1 << ' ' << n2 << '\n'
		<< s1 << ' ' << s2 << ' ' << s3 << '\n';
	for (auto p : m)
		std::cout << p.first << ' ' << p.second << '\n';
	//for (auto n : f.mem)
	//	std::cout << n << ' ';
	//for (auto n : f.mem2)
	//	std::cout << n << ' ';
 
	return 0;
}
 
 
// reference: https://mbevin.wordpress.com/2012/11/16/uniform-initialization/
int test_init_list2()
{
	int arr[]          { 1, 2, 3, 4, 5 };
	std::vector<int> v{ 1, 2, 3, 4, 5 };
	std::set<int> s{ 1, 2, 3, 4, 5 };
	std::map<int, std::string> m{ { 0, "zero" }, { 1, "one" }, { 2, "two" } };
 
	return 0;
}
 
///
// reference: https://mbevin.wordpress.com/2012/11/16/uniform-initialization/
// 'aggregate' class - no user-declared constructor, no private/protected members, no base, no virtual function
struct ClassA {
	int x;
	double y;
};
 
// non-aggregate class
class ClassB {
private:
	int x;
	double y;
public:
	ClassB(int _x, double _y) :x(_x), y(_y) {}
};
 
std::pair<double, double> multiplyVectors(
	std::pair<double, double> v1,
	std::pair<double, double> v2) {
	return{ v1.first*v2.first, v1.second*v2.second };
}
 
int test_init_list3()
{
	int i{ 3 };
	int j{}; // empty braces initialize the object to it's default (0)
	std::string s{ "hello" };
 
	ClassA objA1{};
	ClassA objA2{ 1, 2.0 };
	ClassB objB1{ 1, 2.0 };
	ClassA arrOfAs[] = { { 1, 1.0 }, { 2, 2.0 }, { 3, 3.0 } };
 
	// ouch, the theory is that this should work in C++11, however this doesn't compile, at least with clang, comments?
	ClassB arrOfBs[] = { { 1, 1.0 }, { 2, 2.0 }, { 3, 3.0 } };
 
	// however, this does work
	std::vector<ClassB> vectorOfBs = { { 1, 1.0 }, { 2, 2.0 }, { 3, 3.0 } };
 
	auto result = multiplyVectors({ 1.0, 2.0 }, { 3.0, 4.0 });
 
	return 0;
}

GitHub: https://github.com/fengbingchun/Messy_Test

接著看一下Blackops同學(xué)的補(bǔ)充

由于最近數(shù)據(jù)結(jié)構(gòu)有個(gè)實(shí)驗(yàn)報(bào)告說是要對(duì)字符串進(jìn)行排序,想偷個(gè)懶不想一個(gè)一個(gè)地賦值,雖然可以用strcpy和傳入二級(jí)指針的形式直接寫,但是這樣感覺不美觀漂亮。

  然后就去膜了一下C++11的新特性——初始化列表,概念就不說了,就講下這東西具體怎么用吧,就是正常的寫一個(gè)構(gòu)造函數(shù),然后把參數(shù)改為initializer_list<數(shù)據(jù)類型> &t如圖所示

可以理解為傳入的參數(shù)數(shù)據(jù)被放到了一個(gè)儲(chǔ)存器t中,利用C++11的auto可以直接遍歷這個(gè)儲(chǔ)存器t,然后把遍歷到的值給結(jié)構(gòu)體用。這里用的是char 數(shù)組而不是int是因?yàn)檫@里有一個(gè)問題,如果把initializer_list尖括號(hào)里的類型改為char *,則會(huì)報(bào)錯(cuò),因?yàn)槠胀ǖ?"雙引號(hào)代表的字符串為實(shí)際為const 類型,實(shí)際本身為一個(gè)指針,指向全局const變量中的地址,因此const char *a="123", *b="123",打印a與b的地址會(huì)發(fā)現(xiàn)a與b是相同的,早上就是因?yàn)檫@個(gè)地方百度了一會(huì)兒才明白,另外一個(gè)點(diǎn)就是若聲明的是info數(shù)組,那么顯然要用info的實(shí)例對(duì)象去初始化,因此還要把字符串加上大括號(hào)來形成一個(gè)個(gè)info實(shí)例對(duì)象

下面是完整代碼:

#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
#define CLR(arr,val) memset(arr,val,sizeof(arr))
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
typedef pair<int, int> pii;
typedef long long LL;
const double PI = acos(-1.0);
struct info
{
    char name[20];
    info() {}
    info(const initializer_list<const char *> t)
    {
        for (auto &item : t)
            strcpy(name, item);
    }
};
 
info one[2] = {{"this is one"}, {"this is two"}};
int main(void)
{
    for (auto &it : one)
        cout << it.name << endl;
    return 0;
}

上面是直接用const指針進(jìn)行初始化,那如果我已經(jīng)有了一個(gè)字符串的二維數(shù)組像這樣:char s[maxn][maxn] = {"1", "2", "3", "4"},那如何賦值呢?顯然把每一個(gè)字符串的首地址的地址傳進(jìn)去即可。

#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
#define CLR(arr,val) memset(arr,val,sizeof(arr))
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
typedef pair<int, int> pii;
typedef long long LL;
const double PI = acos(-1.0);
const int N = 20;
char s[N][N] = {"this is one", "this is two", "3", "4"};
struct info
{
    char name[20];
    info() {}
    info(const initializer_list<const char *> t)
    {
        for (auto &item : t)
            strcpy(name, item);
    }
};
 
info one[2] = {{s[0]}, {s[1]}};
int main(void)
{
    for (auto &it : one)
        cout << it.name << endl;
    return 0;
}

似乎更多的情況并不是什么用字符串賦值,而是像int、double或者自定義結(jié)構(gòu)體這樣的賦值,那如何從初始化列表中一個(gè)一個(gè)讀取并連續(xù)地賦值到一維或更高維的數(shù)組里呢?這里用到了C++11的另一個(gè)特性,auto 類型,這樣就可以方便地進(jìn)入初始化列表中去

以HDU 1005為例,如果這題用矩陣快速冪做,那么可以參考以下代碼:

#include <stdio.h>
#include <iostream>
using namespace std;
const int N = 2;
const int MOD = 7;
const int F[3] = {0, 1, 1};
struct Mat
{
    int A[N][N];
    Mat()
    {
        for (int i = 0; i < N; ++i)
            for (int j = 0; j < N; ++j)
                A[i][j] = 0;
    }
    Mat(initializer_list<int> rhs)
    {
        auto it = rhs.begin();
        for (int i = 0; it != rhs.end(); ++it, ++i)
            A[i >> 1][i & 1] = *it;
    }
    Mat operator*(const Mat &rhs)
    {
        Mat c;
        for (int i = 0; i < N; ++i)
            for (int j = 0; j < N; ++j)
                for (int k = 0; k < N; ++k)
                    c.A[i][j] = (c.A[i][j] + A[i][k] * rhs.A[k][j]) % MOD;
        return c;
    }
    friend Mat operator^(Mat a, int b)
    {
        Mat r;
        for (int i = 0; i < N; ++i)
            r.A[i][i] = 1;
        while (b)
        {
            if (b & 1)
                r = r * a;
            a = a * a;
            b >>= 1;
        }
        return r;
    }
};
int main(void)
{
    int A, B, n;
    while (~scanf("%d%d%d", &A, &B, &n) && (A || B || n))
    {
        Mat left =
        {
            A, B,
            1, 0
        };
        Mat right =
        {
            F[2], 0,
            F[1], 0
        };
        if (n <= 2)
            printf("%d\n", F[n]);
        else
        {
            left = left ^ (n - 2);
            Mat resultMat = left * right;
            printf("%d\n", resultMat.A[0][0]);
        }
    }
    return 0;
}

到此這篇關(guān)于C++11中初始化列表initializer lists的使用方法的文章就介紹到這了,更多相關(guān)initializer lists初始化列表內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C/C++預(yù)處理淺析使用形式

    C/C++預(yù)處理淺析使用形式

    預(yù)處理是指在進(jìn)行編譯的詞法掃描和語法分析之前所作的工作。預(yù)處理指令指示在程序正式編譯前就由編譯器進(jìn)行的操作,可放在程序中任何位置。處理完畢自動(dòng)進(jìn)入對(duì)源程序的編譯。C/C++中的預(yù)處理主要包含三種:文件包含、宏定義、條件編譯
    2022-09-09
  • C++存儲(chǔ)鏈接性原理詳解

    C++存儲(chǔ)鏈接性原理詳解

    這篇文章主要為大家介紹了C++存儲(chǔ)鏈接性原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • 簡單了解C++常見編程問題解決方案

    簡單了解C++常見編程問題解決方案

    這篇文章主要介紹了C++常見編程問題解決方案,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-07-07
  • c語言通過opencv實(shí)現(xiàn)輪廓處理與切割

    c語言通過opencv實(shí)現(xiàn)輪廓處理與切割

    這篇文章主要介紹了c語言通過opencv實(shí)現(xiàn)輪廓處理與切割,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2018-01-01
  • C語言中順序棧和鏈棧的定義和使用詳解

    C語言中順序棧和鏈棧的定義和使用詳解

    這篇文章主要為大家詳細(xì)介紹了C語言中順序棧和鏈棧的定義和使用,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C語言有一定的幫助,感興趣的小伙伴可以了解一下
    2022-10-10
  • 關(guān)于C/C++中static關(guān)鍵字的作用總結(jié)

    關(guān)于C/C++中static關(guān)鍵字的作用總結(jié)

    以下是對(duì)C/C++中static關(guān)鍵字的作用進(jìn)行了總結(jié)介紹,需要的朋友可以過來參考下
    2013-09-09
  • C++ 動(dòng)態(tài)創(chuàng)建按鈕及 按鈕的消息響應(yīng)

    C++ 動(dòng)態(tài)創(chuàng)建按鈕及 按鈕的消息響應(yīng)

    這篇文章主要介紹了C++ 動(dòng)態(tài)創(chuàng)建按鈕及 按鈕的消息響應(yīng)的相關(guān)資料,需要的朋友可以參考下
    2015-06-06
  • C++中的數(shù)字轉(zhuǎn)字符串to_string

    C++中的數(shù)字轉(zhuǎn)字符串to_string

    這篇文章主要介紹了C++中的數(shù)字轉(zhuǎn)字符串to_string,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • C++ 虛函數(shù)及虛函數(shù)表詳解

    C++ 虛函數(shù)及虛函數(shù)表詳解

    這篇文章主要介紹了c++ 虛函數(shù)及虛函數(shù)表詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-11-11
  • C++連連看判定圖形消除算法

    C++連連看判定圖形消除算法

    這篇文章主要為大家詳細(xì)介紹了C++連連看判定圖形消除算法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-12-12

最新評(píng)論