色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

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

CPP開發(fā)者 ? 來源:高性能架構(gòu)探索 ? 2023-08-03 15:34 ? 次閱讀
動機

std::mapinsert方法返回std::pair,兩個元素分別是指向所插入鍵值對的迭代器與指示是否新插入元素的布爾值,而std::map::iterator解引用又得到鍵值對std::pair。在一個涉及std::map算法中,有可能出現(xiàn)大量的firstsecond,讓人不知所措。

#include
#include

intmain()
{
typedefstd::mapMap;
Mapmap;
std::pairresult=map.insert(Map::value_type(1,2));
if(result.second)
std::cout<first<second<

C++11標準庫添加了std::tie,用若干引用構(gòu)造出一個std::tuple,對它賦以std::tuple對象可以給其中的引用一一賦值(二元std::tuple可以由std::pair構(gòu)造或賦值)。std::ignore是一個占位符,所在位置的賦值被忽略。

#include
#include
#include

intmain()
{
std::mapmap;
boolinserted;
std::ignore,inserted)=map.insert({1,2});
if(inserted)
std::cout<

但是這種方法仍遠不完美,因為:

?變量必須事先單獨聲明,其類型都需顯式表示,無法自動推導(dǎo);?對于默認構(gòu)造函數(shù)執(zhí)行零初始化的類型,零初始化的過程是多余的;?也許根本沒有可用的默認構(gòu)造函數(shù),如std::ofstream。

為此,C++17引入了結(jié)構(gòu)化綁定(structured binding)。

#include
#include

intmain()
{
std::mapmap;
auto&&[iter,inserted]=map.insert({1,2});
if(inserted)
std::cout<

結(jié)構(gòu)化綁定這一語言特性在提議的階段曾被稱為分解聲明(decomposition declaration),后來又被改回結(jié)構(gòu)化綁定。這個名字想強調(diào)的是,結(jié)構(gòu)化綁定的意義重在綁定而非聲明。

語法

結(jié)構(gòu)化綁定有三種語法:

attr(optional)cv-autoref-operator(optional)[identifier-list]=expression;
attr(optional)cv-autoref-operator(optional)[identifier-list]{expression};
attr(optional)cv-autoref-operator(optional)[identifier-list](expression);

其中,attr(optional)為可選的attributescv-auto為可能有constvolatile修飾的auto,ref-operator(optional)為可選的&&&,identifier-list為逗號分隔的標識符,expression為單個表達式。

另外再定義initializer= expression、{ expression }( expression ),換言之上面三種語法有統(tǒng)一的形式attr(optional) cv-auto ref-operator(optional) [ identifier-list ] initializer;。

整個語句是一個結(jié)構(gòu)化綁定聲明,標識符也稱為結(jié)構(gòu)化綁定(structured bindings),不過兩處“binding”的詞性不同。

順帶一提,C++20中volatile的許多用法都被廢棄了。

行為

結(jié)構(gòu)化綁定有三類行為,與上面的三種語法之間沒有對應(yīng)關(guān)系。

第一種情況,expression是數(shù)組,identifier-list的長度必須與數(shù)組長度相等。

第二種情況,對于expression的類型E,std::tuple_size是一個完整類型,則稱E為類元組(tuple-like)類型。在STL中,std::array、std::pairstd::tuple都是這樣的類型。此時,identifier-list的長度必須與std::tuple_size::value相等,每個標識符的類型都通過std::tuple_element推導(dǎo)出(具體見后文),用成員get()get(e)初始化。顯然,這些標準庫設(shè)施是與語言核心綁定的。

第三種情況,E是非union類類型,綁定非靜態(tài)數(shù)據(jù)成員。所有非靜態(tài)數(shù)據(jù)成員都必須是public訪問屬性,全部在E中,或全部在E的一個基類中(即不能分散在多個類中)。identifier-list按照類中非靜態(tài)數(shù)據(jù)成員的聲明順序綁定,數(shù)量相等。

應(yīng)用

結(jié)構(gòu)化綁定擅長處理純數(shù)據(jù)類型,包括自定義類型與std::tuple等,給實例的每一個字段分配一個變量名:

#include

structPoint
{
doublex,y;
};

Pointmidpoint(constPoint&p1,constPoint&p2)
{
return{(p1.x+p2.x)/2,(p1.y+p2.y)/2};
}

intmain()
{
Pointp1{1,2};
Pointp2{3,4};
auto[x,y]=midpoint(p1,p2);
std::cout<

配合其他語法糖,現(xiàn)代C++代碼可以很優(yōu)雅:

#include
#include

intmain()
{
std::mapmap;
if(auto&&[iter,inserted]=map.insert({1,2});inserted)
std::cout<

利用結(jié)構(gòu)化綁定在類元組類型上的行為,我們可以改變數(shù)據(jù)類型的結(jié)構(gòu)化綁定細節(jié),包括類型轉(zhuǎn)換、是否拷貝等:

#include
#include
#include

classTranscript{/*...*/};

classStudent
{
public:
constchar*name;
Transcriptscore;
std::stringgetName()const{returnname;}
constTranscript&getScore()const{returnscore;}
template
decltype(auto)get()const
{
ifconstexpr(I==0)
returngetName();
elseifconstexpr(I==1)
returngetScore();
else
static_assert(I
structtuple_size
:std::integral_constant{};

template<>
structtuple_element<0,?Student>{usingtype=decltype(std::declval().getName());};

template<>
structtuple_element<1,?Student>{usingtype=decltype(std::declval().getScore());};
}

intmain()
{
std::cout<

Student是一個數(shù)據(jù)類型,有兩個字段namescore。name是一個C風(fēng)格字符串,它大概是從C代碼繼承來的,我希望客戶能用上C++風(fēng)格的std::string;score屬于Transcript類型,表示學(xué)生的成績單,這個結(jié)構(gòu)比較大,我希望能傳遞const引用以避免不必要的拷貝。為此,我寫明了三要素:std::tuple_size、std::tuple_elementget。這種機制給了結(jié)構(gòu)化綁定很強的靈活性。

細節(jié)

#include
#include
#include

intmain()
{
std::pairpair{1,2.0};
intnumber=3;
std::tupletuple(number);
constauto&[i,f]=pair;
//i=4;//error
constauto&[ri]=tuple;
ri=5;
}

如果結(jié)構(gòu)化綁定i被聲明為const auto&,對應(yīng)的類型為int,那么它應(yīng)該是個const int&吧?i = 4;出錯了,看起來正是如此。但是如何解釋ri = 5;是合法的呢?

這個問題需要系統(tǒng)地從頭談起。先引入一個名字e,E為其類型:

?當(dāng)expression是數(shù)組類型A,且ref-operator不存在時,Ecv A,每個元素由expression中的對應(yīng)元素拷貝(= expression)或直接初始化({ expression }( expression );?否則,相當(dāng)于定義eattr cv-auto ref-operator e initializer;。

也就是說,方括號前面的修飾符都是作用于e的,而不是那些新聲明的變量。至于為什么第一條會獨立出來,這是因為在標準C++中第二條的形式不能用于數(shù)組拷貝。

然后分三種情況討論:

?數(shù)組情形,ET的數(shù)組類型,則每個結(jié)構(gòu)化綁定都是指向e數(shù)組中元素的左值;被引類型(referenced type)為T;——結(jié)構(gòu)化綁定是左值,不是左值引用:int array[2]{ 1, 2 }; auto& [i, j] = array; static_assert(!std::is_reference_v);;?類元組情形,如果e是左值引用,則e是左值(lvalue),否則是消亡值(xvalue);記Tistd::tuple_element::type,則結(jié)構(gòu)化綁定vi的類型是Ti的引用;當(dāng)get返回左值引用時是左值引用,否則是右值引用;被引類型為Ti;——decltype對結(jié)構(gòu)化綁定有特殊處理,產(chǎn)生被引類型,在類元組情形下結(jié)構(gòu)化綁定的類型與被引類型是不同的;?數(shù)據(jù)成員情形,與數(shù)組類似,設(shè)數(shù)據(jù)成員mi被聲明為Ti類型,則結(jié)構(gòu)化綁定的類型是指向cv Ti的左值(同樣不是左值引用);被引類型為cv Ti。

至此,我想“結(jié)構(gòu)化綁定”的意義已經(jīng)明確了:標識符總是綁定一個對象,該對象是另一個對象的成員(或數(shù)組元素),后者或是拷貝或是引用(引用不是對象,意會即可)。與引用類似,結(jié)構(gòu)化綁定都是既有對象的別名(這個對象可能是隱式的);與引用不同,結(jié)構(gòu)化綁定不一定是引用類型。

(不理解的話可以參考N465911.5節(jié),盡管你很可能會更加看不懂……)

現(xiàn)在可以解釋riconst的現(xiàn)象了:編譯器先創(chuàng)建了變量const auto& e = tuple;,Econst std::tuple&std::tuple_element<0, E>::typeint&,std::get<0>(e)同樣返回int&,故riint&類型。

在面向底層的C++編程中常用union和位域(bit field),結(jié)構(gòu)化綁定支持這樣的數(shù)據(jù)成員。如果類有union類型成員,它必須是命名的,綁定的標識符的類型為該union類型的左值;如果有未命名的union成員,則這個類不能用于結(jié)構(gòu)化綁定。

C++中不存在位域的指針和引用,但結(jié)構(gòu)化綁定可以是指向位域的左值:

#include

structBitField
{
intf1:4;
intf2:4;
intf3:4;
};

intmain()
{
BitFieldb{1,2,3};
auto&[f1,f2,f3]=b;
f2=4;
autoprint=[&]{std::cout<

程序輸出:

143
153

f2的功能就像位域的引用一樣,既能寫回原值,又不會超出位域的范圍。

還有一些語法細節(jié),比如get的名字查找、std::tuple_size沒有value、explicit拷貝構(gòu)造函數(shù)等,除非是深挖語法的language lawyer,在實際開發(fā)中不必糾結(jié)(上面這一堆已經(jīng)可以算language lawyer了吧)。

局限

以上代碼示例應(yīng)該已經(jīng)囊括了所有類型的結(jié)構(gòu)化綁定應(yīng)用,你能想象到的其他語法都是錯的,包括但不限于:

?std::initializer_list初始化;因為std::initializer_list的長度是動態(tài)的,但結(jié)構(gòu)化綁定的標識符數(shù)量是靜態(tài)的。?用列表初始化——auto [x,y,z] = {1, "xyzzy"s, 3.14159};;這相當(dāng)于聲明了三個變量,但結(jié)構(gòu)化綁定的意圖在于綁定而非聲明。?不聲明而直接綁定——[iter, success] = mymap.insert(value);;這相當(dāng)于用std::tie,所以請繼續(xù)用std::tie。另外,由[開始可能與attributes混淆,給編譯器和編譯器設(shè)計者帶來壓力。?指明結(jié)構(gòu)化綁定的修飾符——auto [& x, const y, const& z] = f();;同樣是脫離了結(jié)構(gòu)化綁定的意圖。如果需要這樣的功能,或者一個個定義變量,或者手動寫上三要素。?指明結(jié)構(gòu)化綁定的類型——SomeClass [x, y] = f();auto [x, std::string y] = f();;第一種可用auto [x, y] = SomeClass{ f() };代替;第二種同上一條。?顯式忽略一個結(jié)構(gòu)化綁定——auto [x, std::ignore, z] = f();;消除編譯器警告是一個理由,但是auto [x, y, z] = f(); (void)y;亦可。這還涉及一些語言問題,請移步P0144R23.8節(jié)。?標識符嵌套——std::tuple, T4> f(); auto [ w, [x, y], z ] = f();;多寫一行吧。[同樣可能與attributes混淆。

以上語法都沒有納入C++20標準,不過可能在將來成為C++語法的擴展。

延伸

C++17的新特性不是孤立的,與結(jié)構(gòu)化綁定相關(guān)的有:

?類模板參數(shù)推導(dǎo)(class template argument deduction,CTAD,由構(gòu)造函數(shù)參數(shù)推導(dǎo)類模板參數(shù);?拷貝省略(copy elision),保證NRV(named return value)優(yōu)化;?constexprif,簡化泛型代碼,消除部分SFINAE;?帶初始化的條件分支語句:語法糖,使代碼更加優(yōu)雅。


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4790

    瀏覽量

    68649
  • 編譯器
    +關(guān)注

    關(guān)注

    1

    文章

    1634

    瀏覽量

    49141
  • 結(jié)構(gòu)化
    +關(guān)注

    關(guān)注

    0

    文章

    27

    瀏覽量

    10317

原文標題:聊聊結(jié)構(gòu)化綁定

文章出處:【微信號:CPP開發(fā)者,微信公眾號:CPP開發(fā)者】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    結(jié)構(gòu)化布線系統(tǒng)有哪些難題

      在布線系統(tǒng)中,結(jié)構(gòu)化布線也是非常重要的一環(huán),這里本文給大家主要講解了結(jié)構(gòu)化布線系統(tǒng)的規(guī)劃、安裝以及投資成本等問題,希望對您有所幫助。  結(jié)構(gòu)化布線系統(tǒng)規(guī)劃  大多數(shù)電纜廠商為它們的產(chǎn)品規(guī)定了15
    發(fā)表于 05-19 13:46

    TrustZone結(jié)構(gòu)化消息是什么?

    大家好,我已閱讀任何與TrustZone相關(guān)的內(nèi)容,但我無法弄清楚這兩個世界是如何相互溝通的。我所能找到的只是TrustZone API規(guī)范中的內(nèi)容:客戶端和服務(wù)可以通過兩種機制進行通信:結(jié)構(gòu)化
    發(fā)表于 03-20 08:58

    Deeplearningai結(jié)構(gòu)化機器學(xué)習(xí)項目

    Deeplearningai 結(jié)構(gòu)化機器學(xué)習(xí)項目 Week2 6-10
    發(fā)表于 05-18 15:12

    請問如何借助SC Express減少結(jié)構(gòu)化測試次數(shù)?

    如何借助SC Express減少結(jié)構(gòu)化測試次數(shù)?
    發(fā)表于 05-11 06:46

    怎么實現(xiàn)基于結(jié)構(gòu)化方法的無線傳感器網(wǎng)絡(luò)設(shè)計?

    怎么實現(xiàn)基于結(jié)構(gòu)化方法的無線傳感器網(wǎng)絡(luò)設(shè)計?
    發(fā)表于 05-31 06:34

    結(jié)構(gòu)化設(shè)計分為哪幾部分?結(jié)構(gòu)化設(shè)計的要求有哪些

    結(jié)構(gòu)化設(shè)計分為哪幾部分?結(jié)構(gòu)化設(shè)計的要求有哪些?結(jié)構(gòu)化設(shè)計主要包括哪些部分?
    發(fā)表于 12-23 06:15

    結(jié)構(gòu)化布線的綜合說明

    結(jié)構(gòu)化布線的綜合說明 一、結(jié)構(gòu)化布線系統(tǒng)簡介     隨著計算機和通信技術(shù)的飛速發(fā)展,網(wǎng)絡(luò)應(yīng)用
    發(fā)表于 04-14 17:16 ?744次閱讀

    探究最佳的結(jié)構(gòu)化ASIC設(shè)計方法

    由于與深亞微米標準單元ASIC相關(guān)的非重復(fù)性工程費用(NRE)越來越大,設(shè)計周期又很長,因此利用結(jié)構(gòu)化ASIC進行定制IC設(shè)計的吸引力正變得越來越大。結(jié)構(gòu)化ASIC能以極具競爭力的單位成
    發(fā)表于 05-02 10:39 ?1875次閱讀
    探究最佳的<b class='flag-5'>結(jié)構(gòu)化</b>ASIC設(shè)計方法

    什么叫結(jié)構(gòu)化的算法_算法和結(jié)構(gòu)化數(shù)據(jù)初識

    結(jié)構(gòu)化算法是由一些基本結(jié)構(gòu)順序組成的,就是把一個大的功能的實現(xiàn)分隔為許多個小功能的實現(xiàn)。在基本結(jié)構(gòu)之間不存在向前或向后的跳轉(zhuǎn),流程的轉(zhuǎn)移只存在于一個基本的結(jié)構(gòu)范圍內(nèi)。一個非
    發(fā)表于 01-03 16:09 ?1.2w次閱讀
    什么叫<b class='flag-5'>結(jié)構(gòu)化</b>的算法_算法和<b class='flag-5'>結(jié)構(gòu)化</b>數(shù)據(jù)初識

    結(jié)構(gòu)化布線系統(tǒng)的四點注意事項

    布線系統(tǒng)結(jié)構(gòu)化 結(jié)構(gòu)化布線 title=結(jié)構(gòu)化布線結(jié)構(gòu)化布線 title=結(jié)構(gòu)化布線結(jié)構(gòu)化布線系
    發(fā)表于 10-16 10:52 ?1241次閱讀

    安防監(jiān)控視頻結(jié)構(gòu)化那些事兒

    即便不考慮各個監(jiān)控系統(tǒng)之間的信息關(guān)聯(lián),光瀏覽這些視頻就需要花費大量的人力物力。解決這一問題的核心技術(shù)即視頻結(jié)構(gòu)化描述技術(shù),將海量視頻或圖片的非結(jié)構(gòu)化數(shù)據(jù)提取并轉(zhuǎn)化為結(jié)構(gòu)化信息描述。
    的頭像 發(fā)表于 03-20 10:20 ?3261次閱讀

    FPGA模塊設(shè)計與AlteraHardCopy結(jié)構(gòu)化ASIC

    本文檔的主要內(nèi)容詳細介紹的是FPGA模塊設(shè)計與AlteraHardCopy結(jié)構(gòu)化ASIC。
    發(fā)表于 01-20 17:03 ?6次下載
    FPGA模塊<b class='flag-5'>化</b>設(shè)計與AlteraHardCopy<b class='flag-5'>結(jié)構(gòu)化</b>ASIC

    CFD 設(shè)計利器:結(jié)構(gòu)化和非結(jié)構(gòu)化網(wǎng)格的組合使用

    在CFD的發(fā)展歷史中,結(jié)構(gòu)化網(wǎng)格出現(xiàn)最早,至今仍在使用。結(jié)構(gòu)化網(wǎng)格有幾個主要優(yōu)點,如精度高、生成速度快、單元分布均勻。有些工具擅長繪制這類網(wǎng)格,例如CadenceFidelityAutomesh
    的頭像 發(fā)表于 12-23 08:12 ?1958次閱讀
    CFD 設(shè)計利器:<b class='flag-5'>結(jié)構(gòu)化</b>和非<b class='flag-5'>結(jié)構(gòu)化</b>網(wǎng)格的組合使用

    結(jié)構(gòu)化布線的好處多嗎

    結(jié)構(gòu)化布線是網(wǎng)絡(luò)系統(tǒng)中的重要組成部分,因為它為數(shù)據(jù)傳輸提供了強大、可擴展且可靠的基礎(chǔ)。通過遵守全球公認的標準,結(jié)構(gòu)化布線可促進高速連接、簡化故障排除并確保未來的可擴展性??紤]到這些優(yōu)勢,企業(yè)應(yīng)優(yōu)先
    的頭像 發(fā)表于 04-07 11:15 ?445次閱讀

    什么是結(jié)構(gòu)化網(wǎng)絡(luò)布線?結(jié)構(gòu)化網(wǎng)絡(luò)布線有哪些好處?

    在電纜領(lǐng)域,結(jié)構(gòu)化網(wǎng)絡(luò)布線這個術(shù)語經(jīng)常被提及。人們將其用作流行語,但它的真正含義是什么?結(jié)構(gòu)化布線到底是什么? 為了了解真正的含義,讓我們看它的一些相關(guān)定義。 根據(jù)光纖協(xié)會的說法,結(jié)構(gòu)化布線是由
    的頭像 發(fā)表于 04-11 11:54 ?531次閱讀
    主站蜘蛛池模板: 野花影院手机在线观看 | 亚洲国产日韩欧美高清片a| 一区二区三区福利视频| 国产精品18久久久久久白浆.| 蜜芽在线影片| 一级淫片bbbxxx| 国产在线观看码高清视频| 日产久久视频| www.伊人网| 琪琪的色原网站| a一级毛片视频免费看| 美女脱了内裤张开腿让男人桶到爽| 一边亲着一面膜下的免费过程 | 国精产品一区一区三区有限 | 一二三四在线观看高清电视剧 | 动漫美女人物被黄漫在线看| 男人天堂黄色| 99re6久久在热线视频| 免费国产久久啪在线| 最近韩国日本免费观看mv免费版| 久久99国产综合精品AV蜜桃| 亚洲欧美中文在线一区| 国产亚洲综合视频| 亚洲精品乱码8久久久久久日本| 国产在线观看黄| 亚洲绝美精品一区二区| 狠狠色狠狠色综合日日32| 亚洲欧美日韩国产手机在线| 国产在线精品一区二区在线看| 无毒成人社区| 国产精品久久久久久久A片冻果 | 好大快用力深一点h视频| 亚洲精品成人AV在线观看爽翻| 好吊射视频988gaocom| 伊人热| 蜜芽视频在线观看视频免费播放 | 青娱乐极品视觉盛宴av| 成人性生交大片免费看4| 色欲AV亚洲永久无码精品麻豆| 国产精品福利片| 亚洲haose在线观看|