最近幾週,C++委員會在奧盧(Oulu)召開會議,C++17的最終特性得以確定,並且它即將成為一個國際標準。在傑克遜維爾(Jacksonville)召開的最後那次會議之後,我對於C++17能給人帶來大驚喜未抱太大的希望,但是奧盧會議卻努力地為C++17新標準增加一些重要而且有趣的特性。 Reddit頁面提供了一個很好的C++17特性總覽,並且,Herb Sutter在最近的CppCast站點上(還有他的行程報道) 也給出了有關C++17特性的很好的見解。另外,Michael Wong為我們呈現出了C++17特性的更完整的概述 。
先說重要的
正如我前面所說,在傑克遜維爾(Jacksonville)召開的那次會議之後,C++17的許多特性已經非常明確。對於是否轉向C++17,我寫了一篇包含三個部分的部落格系列文章,提出了一些建議。我們將進入C++的新世紀,和強大的技術規範一同發布的還有相關的標準,這些都將成為下一代C++標準的組成部分。這意味著,那些非C++17的特性(例如,Concepts或Modules思想)將在即將發布的編譯器中作為插件使用。 Visual Studio目前提供了modules,而GCC是第一個支援concept的編譯器。 Clang也支援modules,而Visual Studio和Clang不久都會實作基於module TS的規格。
而且,我在想,接下來的兩次會議將主要處理一些評論、回饋和各個國家團體(又稱ISO成員代表團)所提出的問題。 C++的標準不會增加新內容,而是會有一些或多或少的改變。但還是希望所有的這些特性能在最終的審核中獲得通過。
C++17的最終亮點
std::variant(變體)
讓我們從最讓我驚訝的地方開始:最讓我驚訝的地方開始:最讓我驚訝。是的,嚴肅的說,C++17帶來了std::variant。這太棒了,並且為將來基於變體和其他相關想法的特徵鋪平了道路。例如,樣式匹配,C++上關於這個有一個非常好的談話。根據David Sankel所說,std::variant是按照boost::variant和或其他variant庫進行設計的。與boost::variant有非常相似的API
variant<int, float> v, w; v = 12;int i = get<int>(v); w = get<int>(v); w = get<0>(v); // same effect as the previous linew = v; // same effect as the previous lineget<double>(v); // ill formedget<3>(v); // ill formedtry { get<float>(w); // will throw.}catch (bad_variant_access&) {}
能看到這個特徵收錄到了C++17標準中,而不是採用TS detour,非常高興。
if constexpr(expression)
這是static if的C++版本(差不多)。對我來說這是Jacksonville的亮點之一,那時,這並沒有讓它採用。不負眾望,它通過了Oulu對於C++17的最終回顧。有了它,如果在編譯過程中,一個constexpr被評估為真,C++可以輕鬆的讓某些語句塊編譯:
if constexpr (std::is_integer ...) { //integerstuff } else if constexpr (std::is_floating_point ...) { //floatingpointstuff } else { // NaN ;) }
這個例子顯式的說明了,constexpr必須在編譯中被判斷為真,但是對於static_assert沒有影響。語句區塊中沒有被選定的static_assert仍然會觸發。這對於標準來說是不恰當的。
還有一個有趣的地方:這個特徵寫為if constexpr,但是標準的拼寫仍然將其命名為constexpr if,但是將它定義為了if constexpr。
在模板中使用auto
對於C++14,匿名表達式能使用auto來定義泛型參數。 目前定義(非型別)模板參數也是可以使用auto的。這使得編寫模板程式碼變得更加容易,因為auto要比class或typename更簡短。定義可變長模板參數也可以使用auto,例如:template
結構化的綁定
直至現在,仍在使用一個有名的訣竅,就是隨意使用std::tie來直接分配一個元組或者一對不同的變量,而不需要手動處理結果類型。這是一個技巧,而且變數必須存在, 現在你可以在一行中宣告變數並進行初始化:
auto [a , b , c] = getvalues();
括號不能少,getvalues回傳一個元組。在建議中沒有提及std::pair,所以使用pair是否也能正常運作並不明確,在一些插入(insert)方法中它是由STL傳回的。
if 和 switch 與 初始化
現在 if 語句中可以定義變數了:if(int x = 42; true != false),這可以結合前面的建議。在一個 if 語句定義的變數在它的 else 部分也是有效的。我記得現代 C++ 設計曾提示透過花括號這樣一個技巧來實現這個功能,但這只是單一變數。
使用這個案例是有趣的,例如在 if 或 switch 中進行鎖定,所有這些函數返回的狀態碼現在都可以在 if 的內部被處理。本質上來說,這相當於寫成 { var x = value; if(...){}else{}} 。
更多
這還不是全部,比如,為了copy ellision(拷貝去除)的改進,保留了std[0-9]+的名稱空間給未來的標準。還有,對於reddit的看法也有許多有趣的討論和觀點。
C++ 17標準正逐步發展完善,標準化的工具也已成熟且投入使用。這對C++來說是最大的收穫。那些想要給下一個C++標準添磚加瓦的人,或許現在就得開始擬定計畫了。 C++的標準化一直是由志工們來推動的,做這個事情沒有錢拿,大家基本上都是一些日常工作和C++相關的人。建議大家去看看isocpp.org,上面有非常nice且詳細的介紹,同時也有各種各樣的mailing lists(郵件表)和工作小組供大家加入。
以上就是C++17 的最終特性的內容,更多相關內容請關注PHP中文網(www.php.cn)!