日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

变量之--列表初始化和结构化绑定

發(fā)布時(shí)間:2024/4/18 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 变量之--列表初始化和结构化绑定 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

變量之(變長)列表初始化

關(guān)鍵詞

std::initializer_list

解釋

在 C++98/03 中的對象初始化方法有很多種,這無疑增大了學(xué)習(xí)難度。這中情況在C++11中終于得到解決。

先看看沒有C++11的時(shí)候

//初始化列表 int i_arr[3] = { 1, 2, 3 }; //普通數(shù)組 struct A { int x; struct B { int i; int j; } b; } a = { 1, { 2, 3 } }; //POD類型 //拷貝初始化(copy-initialization) int i = 0; class Foo { public: Foo(int) {} } foo = 123; //需要拷貝構(gòu)造函數(shù) //直接初始化(direct-initialization) int j(0); Foo bar(123); int data = 0; //賦值初始化 int data = {0}; //花括號初始化 int data(0); //構(gòu)造初始化 int data{0}; //花括號初始化

這些不同的初始化方法,都有各自的適用范圍和作用。最關(guān)鍵的是,這些種類繁多的初始化方法,沒有一種可以通用所有情況。

為了統(tǒng)一初始化方式,并且讓初始化行為具有確定的效果,C++11 中提出了列表初始化(List-initialization)的概念。

?

統(tǒng)一的初始化

舉個(gè)小例子看看C++11變長初始化列表是怎么用的

#include <initializer_list>class MagicFoo{public:std::vector<int> vec;MagicFoo(std::initializer_list<int> list){for (std::initializer_list<int>::iterator it = list.begin(); it!= list.end(); ++it)vec.push_back(*it);}};int main(){ // after C++11MagicFoo magicFoo = {1, 2, 3, 4, 5};for (auto it : magicFoo.vec) std::cout << it << std::endl;}

這里需要注意的是,雖然使用了等于號,但它仍然是列表初始化,因此,私有的拷貝構(gòu)造并不會影響到它。

總結(jié)

C++11統(tǒng)一了所有初始化方式,都變成了下面的形式:

Foo a3 = { 123 }; Foo a4 { 123 };

除了上面所述的內(nèi)容之外,列表初始化還可以直接使用在函數(shù)的返回值上:

struct Foo { Foo(int, double) {} }; Foo func(void) { return { 123, 321.0 }; }

這里的 return 語句就如同返回了一個(gè) Foo(123, 321.0)。

?

結(jié)構(gòu)化綁定

簡介

C++17語言上(語言特性,而不是標(biāo)準(zhǔn)庫新特性)引入了一種結(jié)構(gòu)化綁定的新特性,使用該特性可以利用auto同時(shí)聲明多個(gè)不同類型的變量并即時(shí)從一個(gè)tuple-like對象得到賦值/初始化。
Structured binding不但可以使C++的代碼更加簡潔,而且似乎從語法上更貼近Python這種腳本語言了。另外,auto變量會在編譯時(shí)推導(dǎo)出變量的類型,所以無需擔(dān)心會有運(yùn)行時(shí)效率的下降。而且,好像也并不會影響到編譯效率,這一點(diǎn)尚未看到有實(shí)測。

在C++11的時(shí)候,如果要接收從函數(shù)返回的std::tuple對象,我們可以使用std::tie。

舉個(gè)例子:

#include <iostream>#include <tuple>std::tuple<int, double, std::string> f(){ return std::make_tuple(1, 2.3, "456");}int main(){ // C++17 auto [x, y, z] = f(); std::cout << x << ", " << y << ", " << z << std::endl; //C++11 int a; double b, std::string c; std::tie(a, b, c) = f();std::cout << a << ", " << b << ", " << c << std::endl; return 0;}

結(jié)構(gòu)化綁定聲明?(C++17 起)

下面部分可以忽略。。。只是為了解釋C++17的結(jié)構(gòu)化綁定。

綁定指定名稱到初始化器的子對象或元素。

類似引用,結(jié)構(gòu)化綁定是既存對象的別名。不同于引用的是,結(jié)構(gòu)化綁定的類型不必為引用類型。

定義

attr(可選) cv-autoref-運(yùn)算符(可選) [ 標(biāo)識符列表 ] = 表達(dá)式 ; (1)

attr(可選) cv-autoref-運(yùn)算符(可選) [ 標(biāo)識符列表 ] { 表達(dá)式 } ; (2)

attr(可選) cv-autoref-運(yùn)算符(可選) [ 標(biāo)識符列表 ] ( 表達(dá)式 ) ; (3)

attr -?? 任意數(shù)量的屬性的序列

cv-auto -?? 可有 cv 限定的 auto 類型說明符,亦可包含存儲類說明符 static 或 thread_local ;在 cv 限定符中包含 volatile 是被棄用的 (C++20 起)

ref-運(yùn)算符 ?? - ?? &或 && 之一

標(biāo)識符列表 ? -?? 此聲明所引入的各標(biāo)識符的逗號分隔的列表

表達(dá)式 ? -?? 頂層沒有逗號運(yùn)算符的表達(dá)式(文法上為賦值表達(dá)式),且具有數(shù)組或非聯(lián)合類之一的類型。若表達(dá)式 涉及任何來自 標(biāo)識符列表 的名字,則聲明非良構(gòu)。

情況 1:綁定數(shù)組

標(biāo)識符列表?中的每個(gè)標(biāo)識符均成為指代數(shù)組的對應(yīng)元素的左值。標(biāo)識符的數(shù)量必須等于數(shù)組的元素?cái)?shù)量。

每個(gè)標(biāo)識符的被引用類型都是數(shù)組的元素類型。注意若數(shù)組類型?E?為 cv 限定的,則其元素亦然。

int a[2] = {1,2}; auto [x,y] = a; // 創(chuàng)建 e[2],復(fù)制 a 到 e,然后 x 指代 e[0],y 指代 e[1]auto& [xr, yr] = a; // xr 指代 a[0],yr 指代 a[1]

情況 2:綁定元組式類型

表達(dá)式?std::tuple_size<E>::value?必須是良構(gòu)的整數(shù)常量表達(dá)式,且標(biāo)識符的數(shù)量必須等于?std::tuple_size<E>::value。

對于每個(gè)標(biāo)識符,引入一個(gè)類型為“std::tuple_element<i, E>::type?的引用”的變量:若其對應(yīng)初始化器是左值,則為左值引用,否則為右值引用。第 i 個(gè)變量的初始化器

  • 若在?E?的作用域中對標(biāo)識符?get?按類成員訪問進(jìn)行的查找中,至少找到一個(gè)聲明是首個(gè)模板形參為非類型形參的函數(shù)模板,則為?e.get<i>()

  • 否則為?get<i>(e),其中?get?只進(jìn)行實(shí)參依賴查找,忽略非 ADL 的查找。

這些初始化器表達(dá)式中,若實(shí)體?e?的類型為左值引用(這僅在?ref-運(yùn)算符?為?&,或?yàn)?strong>&&?且初始化器為左值時(shí)才發(fā)生),則?e?為左值,否則為亡值(這實(shí)際上進(jìn)行了一種完美轉(zhuǎn)發(fā)),i?是?std::size_t?的純右值,而且始終將?<i>?解釋為模板形參列表。

變量擁有與?e?相同的存儲期。

然后該標(biāo)識符變成指代與上述變量綁定的對象的左值。

第 i 個(gè)標(biāo)識符的被引用類型為?std::tuple_element<i, E>::type。

float x{};char y{};int z{};std::tuple<float&,char&&,int> tpl(x,std::move(y),z);const auto& [a,b,c] = tpl;// a 指名指代 x 的結(jié)構(gòu)化綁定;decltype(a) 為 float&// b 指名指代 y 的結(jié)構(gòu)化綁定;decltype(b) 為 char&&// c 指名指代 tpl 的第 3 元素的結(jié)構(gòu)化綁定;decltype(c) 為 const int

情況 3:綁定到數(shù)據(jù)成員

E?的所有非靜態(tài)數(shù)據(jù)成員必須都是?E?或?E?的同一基類的直接成員,必須在指名為e.name?時(shí)于結(jié)構(gòu)化綁定的語境中是良構(gòu)的。E?不能有匿名聯(lián)合體成員。標(biāo)識符的數(shù)量必須等于非靜態(tài)數(shù)據(jù)成員的數(shù)量。

標(biāo)識符列表?中的各個(gè)標(biāo)識符,按聲明順序依次成為指代?e?的各個(gè)成員的左值的名字(支持位域);左值的類型是?cv?T_i,其中?cv?是?E?的 cv 限定符且?T_i?是第 i 個(gè)成員的聲明類型。

第 i 個(gè)標(biāo)識符的被引用類型是?cv?T_i。

struct S { int x1 : 2; volatile double y1;};S f(); const auto [x, y] = f(); // x 是標(biāo)識 2 位位域的 const int 左值 // y 是 const volatile double 左值 與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖

總結(jié)

以上是生活随笔為你收集整理的变量之--列表初始化和结构化绑定的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。