MSVC不能返回一個(gè)可以復(fù)制但不能移動(dòng)的對(duì)象
在處理復(fù)制省略時(shí)我遇到了這個(gè)奇怪的行為:類(lèi)對(duì)象{public:Obj()=default;Obj(Objamp;){std::coutlt;lt;<;std::endl;}}};Obj f1(){Obj o;retur
解答動(dòng)態(tài)
F1()上沒(méi)有錯(cuò)誤是clang和gcc中的一個(gè)錯(cuò)誤。它是在clang的主干頂端修復(fù)的。
f1()不符合強(qiáng)制刪除副本的條件。
Deleted函數(shù)參與重載解析。如果選擇它們作為最佳重載,則程序的格式是錯(cuò)誤的。在F1()中,刪除的移動(dòng)構(gòu)造函數(shù)由過(guò)載解決方案.2 in f2()選擇,如C++ 17,保證復(fù)制/移動(dòng)刪除,因此不執(zhí)行移動(dòng)/復(fù)制構(gòu)造函數(shù)上的過(guò)載分辨率。在C++ 11/14中,f2-()也是一個(gè)錯(cuò)誤(同樣錯(cuò)誤(f1)),因?yàn)閺?fù)制/移動(dòng)刪除不保證。2 也看到這個(gè)準(zhǔn)則:永遠(yuǎn)不要?jiǎng)h除那些特殊的移動(dòng)成員,它是在C++ 17之前寫(xiě)的。
OH,我感到慚愧,我剛剛意識(shí)到另一個(gè)答案是Howard Hinnant。有一個(gè)人的作品讓我明白了我在這里痛苦地試圖解釋的東西,這有點(diǎn)可笑……因?yàn)閏opy和move構(gòu)造函數(shù)都是聲明的,所以它們都是存在,尤其是在這里,您需要小心地定義自己的復(fù)制構(gòu)造函數(shù);如果沒(méi)有這一點(diǎn),它將被定義為deleted(參見(jiàn)本演示文稿的第28頁(yè))。第28頁(yè)deleted方面只是定義的細(xì)節(jié),但它們實(shí)際上都被聲明為可以重載分辨率f1()如果發(fā)生復(fù)制省略,則不需要在復(fù)制構(gòu)造函數(shù)和移動(dòng)構(gòu)造函數(shù)之間進(jìn)行選擇;這些都不是用過(guò)了。開(kāi)其他的另一方面,如果沒(méi)有出現(xiàn)復(fù)制省略,則必須選擇最佳重載來(lái)構(gòu)造結(jié)果;這里是move構(gòu)造函數(shù),因?yàn)樗嬖冢暶髁,?qǐng)參見(jiàn)此處),最后發(fā)現(xiàn)定義為deleted,但為時(shí)已晚,已經(jīng)做出了選擇。
在f2()中,顯式請(qǐng)求顯式復(fù)制,那么復(fù)制構(gòu)造函數(shù)是最好的選擇。
這是相當(dāng)令人困惑的,當(dāng)我們讀取=刪除時(shí),我們認(rèn)為?這不能在重載解析中選擇?但這是錯(cuò)誤的;=只有在重載解析之后,當(dāng)發(fā)現(xiàn)更好的匹配時(shí),才考慮刪除。- End
免責(zé)聲明:
本頁(yè)內(nèi)容僅代表作者本人意見(jiàn),若因此產(chǎn)生任何糾紛由作者本人負(fù)責(zé),概與琴島網(wǎng)公司無(wú)關(guān)。本頁(yè)內(nèi)容僅供參考,請(qǐng)您根據(jù)自身實(shí)際情況謹(jǐn)慎操作。尤其涉及您或第三方利益等事項(xiàng),請(qǐng)咨詢(xún)專(zhuān)業(yè)人士處理。