標籤:

C++20 有哪些值得注意的新特性?


就我個人而言,module,coroutine是最期待的,編譯期反射也必須上,否則c++23就沒法上sutter那個大腦洞了( p0707r1) 。

c++20大部分特性例如concept之類的已經很多年了,我記得2000年前B.S.就提過,說實話我已經審美疲勞。反倒是編譯期反射讓我隱約覺得這貨不只能用來實現個系列化,說不定能開發出非常大的腦洞。

關於sutter的腦洞:

Metaclasses: Thoughts on generative C++

Clang 5.0.0 Release Notes

LLVM 5.0發布,最大的改變是支持coroutine,也即MS那個提案。

目前支持coroutine的有vc2015u3和llvm 5.0。看來coroutine進c++20是板上釘釘的事了。


Concept,Module值得一看

coroutine-ts不知是死是活

range-ts不知能不能加入

還有值得關注的

networking-ts

concurrency-ts

metaclass不知能不能加入ts

各種零散小feature

坐等CppCon2017


為什麼會變成這樣呢……第一次有了喜歡的語言。有了能關注的語言。兩件快樂事情重合在一起。而這兩份快樂,又給我帶來更多的快樂。得到的,本該是像夢境一般幸福的時間……但是,為什麼,會變成這樣呢……為什麼C++17毛都沒有呢……為什麼只能做夢下一個版本呢……為什麼會變成這樣呢……

Rust大法好


現在確定的 C++20 特性也不多吧。

20171213 更新:

Coroutine/Ranges/Concepts 已經穩了。

可以看下這裡面的:

制約與概念 - cppreference.com

聚合初始化 - cppreference.com

還有位域帶初始化器等零散特性。

事到如今, SFINAE 有一定發展, Concepts 又經過了削減,實際上兩者已經走得很近了……


說實話,上面那些說沒來得及學C++11/14/17的,你們是認真寫C++的嗎?用C++寫過那麼一點點項目嗎?就隨便說C++17幾點吧:

  1. nested namespace使用起來不是很符合直覺嗎?寫兩次namespace很爽嗎?
  2. 結構化綁定結構在foreach中解構pair,返回值也是,每次寫.first、.second很爽嗎?
  3. constexpr if。。。被enable_if虐過的人都知道constexpr if用起來有多爽。。。

後面不想列了,如果覺得新事物難以接受,那麼不管C++變不變都不是適合你的語言,說說C++20吧,concept啊,最好STL用concept修一下啊,我真是看到一坨坨的編譯錯誤頭大啊。

———————————————————————————

加個說明,這個答案現在看起來有點奇怪了,這是一開始反駁一些人的,一開始這個題目下面有幾個答案都是說C++11/14/17還沒來得及學,C++20怎麼又開始了,現在好像都被摺疊了。


不如考慮把VC++的co_await做進去,寧願不要range這種自己也能做的事情。


Constraints and concepts

從cppreference的摘錄

Class templates, function templates, and non-template functions (typically members of class templates) may be associated with a constraint, which specifies the requirements on template arguments, which can be used to select the most appropriate function overloads and template specializations.

Constraints may also be used to limit automatic type deduction in variable declarations and function return types to only the types that satisfy specified requirements.

Named sets of such requirements are called concepts. Each concept is a predicate, evaluated at compile time, and becomes a part of the interface of a template where it is used as a constraint:

#include &
#include &
using namespace std::literals;

// Declaration of the concept "EqualityComparable", which is satisfied by
// any type T such that for values a and b of type T,
// the expression a==b compiles and its result is convertible to bool
template&
concept bool EqualityComparable = requires(T a, T b) {
{ a == b } -&> bool;
};

void f(EqualityComparable); // declaration of a constrained function template
// template&
// void f(T) requires EqualityComparable&; // long form of the same

int main() {
f("abc"s); // OK, std::string is EqualityComparable
f(std::use_facet&&>(std::locale{})); // Error: not EqualityComparable
}

Violations of constraints are detected at compile time, early in the template instantiation process, which leads to easy to follow error messages.

std::list& l = {3,-1,10};
std::sort(l.begin(), l.end());
//Typical compiler diagnostic without concepts:
// invalid operands to binary expression ("std::_List_iterator&" and
// "std::_List_iterator&")
// std::__lg(__last - __first) * 2);
// ~~~~~~ ^ ~~~~~~~
// ... 50 lines of output ...
//
//Typical compiler diagnostic with concepts:
// error: cannot call std::sort with std::_List_iterator&
// note: concept RandomAccessIterator&&> was not satisfied

The intent of concepts is to model semantic categories (Number, Range, RegularFunction) rather than syntactic restrictions (HasPlus, Array). According to ISO C++ core guideline T.20, "The ability to specify a meaningful semantics is a defining characteristic of a true concept, as opposed to a syntactic constraint."


反正我是準備等公司升級到 CentOS 7 再考慮上 C++14 了,至於現在支持的 C++03,小於 11 版本的 C++ 根本沒法用嘛!還不如用 C(


記得去年七八月份的時候,知乎上就一大堆人在討論C++17有哪些值得注意的新特性什麼的。當時我也很期待,畢竟我最愛的語言終於也可以有一些方便的功能,同時網路庫什麼的雖然沒那麼急切需要,但是聊勝於無嘛,更何況標準庫里提供的,至少不會太差。所以當時就天天看這些內容,把傳說中的C++17的新特性了解了一個遍也學了一個遍。。。恩,後來的結果。。。肯定有些失望。

如今開始討論C++20了,這次我乾脆等標準徹底確定,編譯器徹底支持了再說。(不過試了一下VS2017里對C++17支持的部分,寫起來果然爽一些,以前好多句話實現的功能,現在一句話就好了。而且Concept出來之後,也不用看上千個錯誤信息了,還是期待。)

根據我從去年到最近的了解,看了不少相關的博客和委員會成員的演講,感覺Concept、Reflection和Module進入的希望還是挺大的,Range的希望也挺大,但是之前看過一篇博客,上面說coroutine的希望有些渺茫(更新:嗯。。。又看了一些文章說這個還是很有希望的,不管了,我等吃瓜群眾就等著好了。)。記得去年七月份看過一篇委員會成員寫的文章,意思大概是說C++的特性更迭將不會是以大更新的形式提供了,而是經常性的提供小更新,而這些較為重要的特性,比如Concept,Module,Range這些的,會先以TS的形式存在,然後經過調整或者原封不動的放入標準。感覺這種更新方式。。。像Win10,懷疑這種更新方案就是微軟的人提的。。。

不過還有三年時間,還是可以抱著一絲希望的。反正我倒是比較希望這幾個特性都加進去。。。畢竟我都了解過了,就等著用呢。。。不過在此之前。。。我先去隔壁C#家做做客。希望這三年委員會的人可以把這些東西加進去。

可是。。。我對委員會的拖延症感到擔憂。。。

所以,這個問題的答案完全可以在C++17的問題里找,C++17本應該有的特性大概就是C++20會有的吧。

2017 Toronto ISO C++ Committee Discussion Thread (Concepts in C++20; Coroutines, Ranges and Networking TSes published) ? r/cpp

加上這個鏈接,想獲得正經答案的可以看看。


先把現在還使用的gcc3.*,4.*原地爆炸,再考慮c++20吧,很多廠的gcc連11都不支持,怎麼玩?


C++程序員一到公司,所有員工都看著他笑,
有的叫道,「C++大神,昨晚daily build,你的代碼又編譯失敗了!」

他不回答,對前台秘書說,「晚上加班,要一份宮保雞丁。」便摸出一隻鉛筆登記。

他們又故意的高聲嚷道,「你一定亂造輪子了!」
C++程序員睜大眼睛說,「你怎麼這樣憑空污人清白……」
「什麼清白?我前天親眼見你用了boost,編譯錯誤滿天飛。」

C++程序員便漲紅了臉,額上的青筋條條綻出,爭辯道,「匹配失敗不算錯誤…SFINAE!……編譯器不符合標準,能算BUG么?」

接連便是難懂的話,什麼「一流程序員用C++」,什麼「metaclass」之類,引得眾人都鬨笑起來:公司內外充滿了快活的空氣。

C++程序員自己知道不能和他們談天,便只好向新員工說話。

有一回對我說道,「你寫過代碼么?」我略略點一點頭。
他說,「寫過代碼,我便考你一考。變長參數,怎樣寫的?」

我想,成天寫bug,被發郵件全公司通報批評的人,也配考我么?便回過臉去,不再理會。

C++程序員等了許久,很懇切的說道,「不能寫罷?……我教給你,記著!這些應該記著。將來做架構師的時候,面試別人要用。」

我暗想我和架構師的等級還很遠呢,而且我們架構師從不局限編程語言,採用最合適的框架實現需求,而不什麼都亂用C++造輪子;又好笑,又不耐煩,懶懶的答他道,「誰要你教,不就是三個點么?」

C++程序員顯出極高興的樣子,將兩個指頭的長指甲敲著水杯,點頭說,「對呀對呀!變長參數有四樣寫法,C和C++不一樣,還能用宏實現,你知道么?」

我愈不耐煩了,努著嘴走遠。C++程序員剛打開了VIM,想在上面敲代碼,見我毫不熱心,便又嘆一口氣,顯出極惋惜的樣子。

————————————————

C++大神一來,大家為什麼笑?

因為他的代碼編譯失敗了。

大神為了玩新特性,安裝vs2017,gcc7這種最新編譯器,而公司自動集成是穩定版編譯器,有時候稍不注意,沒有對集成環境進行測試,就容易導致編譯失敗。

而大神肯定要辯解,"明明我編譯過去了",

然而集成測試還是失敗了,這種情況次數多了,大家就要嘲笑。

大神為什麼要加班?

因為他一看編譯失敗了,肯定惹麻煩了。

而且大神不屑於寫單一平台代碼,他得考慮跨平台,考慮各種編譯器,還得關注32/64,他自己給自己安排了各種任務,所以他要加班。

之後大家嚷"一定是亂造輪子了"

大神大囧,這下戳了痛點, 本來就是單一平台的代碼,大神為了各種模式,把虛函數換成boost::signal,把很簡單的iocp用asio各種模式生搬硬套,他自己寫代碼的過程中,就已經產生了無數屏的error, 和他合作的同事,用他的代碼也造成了無數麻煩,之後大家對他這種行為都"敬而遠之"。

大神並不覺得是自己的錯,要是有了C++20的新語法,他就不這麼麻煩造輪子,所以他抱怨錯的不是自己,而是編譯器。

後面的以後接著寫。


歪個樓

其實 c++ 存在於世上好像就是個錯誤,為什麼呢?君不見每次都這些言論:

c++ 不更新,那麼 c++ 藥丸,因為沒人管啦,要棄坑啦

c++ 更新吧,那麼 c++ 藥丸,因為 c++ 已經很複雜了,加那些新東西更沒人用啦

c++ 缺少一些現代語言的特性,那麼 c++ 藥丸,因為 c++ 落伍了啊,比不上 xx 語言啦

c++ 加入了別的語言的特性吧,那麼 c++ 藥丸,因為 c++ 不純粹啦,要這些特性我為啥不直接用 xxx 語言啦

變的是噴的內容,不變的是噴的那群人。


說實話它出什麼新特性我不關心,什麼時候把@Deprecated支持一下就好


其實我們要的只是一個兼容C的Native的C#而已,為什麼C++標準化委員會不能滿足我們呢?(掀桌)


寫作切換新標準沒有收益,讀作不想學習

寫作最老最low的就是最穩定的,讀作不想學習

寫作怕升級版本踩坑,讀作不想學習(以及不想花點時間port)

嗯,很好,你們繼續加油轉管理吧,我來組成學習


這種問題,應該關注的是這樣的人:c++,沒有這種特徵,真不方便!啥時候能把這種特徵加進去呢。

沒到到這個高度的,c++哪個版本都適合。忽然有那麼一天,覺得應該用c++

的某種特性,但仔細查,當前所用版本無此特徵,那就查查最高版本。

一點題外話:如果人工智慧學會了編程,那麼,它用的語言,要麼是c++,要麼是python。

人工智慧編程的情景,簡單的可能是,你對一台人工只能電腦說:「用c++語言,編一段可以編譯、運行的程序,在顯示屏上輸出"hello world!",需要給源代碼加上注釋。」


由於Concept已經是鐵板上釘釘的事,而且GCC已經實現了,估計到C++20語法上也不會有太多的增強.

因此大方面只剩下module和反射了.當然最重要的還是反射,沒有module無非是編譯慢,在功能上是無缺的.沒有反射就麻煩了.

就反射來說,雖然目前的草案並沒有對C++的語法要素全解析,但我估計最終能夠做到解析到每個類,類的模板參數,類中的每個成員,每個函數的參數及其模板參數,肯定不會解析到語句,如果能解析到語句,那就全無敵了.

========================2017-10-20最新修改============================

大家不要對反射期望太高,反射到語句級大家表想了,早在2014年就有人在ISO C++ Standard - Future Proposals的討論組上發了Attribute reflection的想法,最後被拒了.

回復者一開始說對Attribute的反射會改變C++的語義.

然後另一個人認真的說,Attribute的反射不會改變C++的語義.

之後這兩人就開始長長的討論了一番.

反對者可能意識到改變C++的語義這個說法實在站不住腳.

然後有找了一些其它的理由,如,Attribute reflection我沒看出他有什麼大用.

這會為打開程序員"發明"屬性的大門.

至於為什麼需要Attribute reflection,反射雖然提供了一種遍歷符號的機制,但是只能得到每一個符號的name和typename.至於它們的語義我們是不知道,但有時候我們需要知道它們的語義.從C++ 11開始就可以自定義屬性,那麼這個自定義屬性除了對編譯器開發商來說,對普通用戶有什麼用呢,什麼用都沒有,沒有任何語法機制可以解析它,於是有人就想既然有這麼個東西,可不可以把它利用起來.

於是大家想到了如果和反射配合起來,就能標記任何符號的語義.

標記語義有什麼用,最簡單的例子,就是serialization,長期以來C++程序員為了實現自動的serialization想了種種辦法,但是沒有一種簡單而乾淨的辦法,若能反射屬性,那就可以用[[serialize]] int f1;來標記

當然如果不能反射屬性,我們也可以用struct serialize{int f1,f2,f3;};這樣的辦法,當然了一個符號可以有多個屬性,對[[[attr1, attr2,...]] int f1;

我們也可以用struct Attr{AttrIt& f1;AttrIt& f2;}來標記.

雖然不用Attribute reflection也可到達同樣的效果,但是為每個符號寫屬性的方法要乾淨點,也更加符合人的思維習慣.

以前我也提過一個從is_constexpr需求,也是牛頭不對馬嘴的解釋.

我就在想,ISO C++ Standard - Future Proposals每天都有人提出需求,但是最後的C++的特性恐怕沒有一個從那裡提出來的吧,既然這些我認為比較有"通用性"的需求都無法滿足,那些屁不能疼的需求就更不可能實現,那麼這論壇不就是大家心裡安慰劑嗎?

綜上,大家不要對反射程度有太高期望.


就是感嘆為什麼java那麼落後的語言市場佔有那麼大,c++ 則是相對先進但還要被吐槽功能太多。。。


C++走上彎路了...C++17裡面竟然出現了Fold Expression這種意義不明的,為了十分局限的功能創造的新的語法...

C++20不看好

#include &
template &< class First &> auto sum(First first)
{
return first;
}
template &< class First, class ...Args &> auto sum(First first, Args ...args)
{
return first + sum(args...);
}
int main()
{
printf("%d
", sum(1, 2, 3, 4, 5));
printf("%d
", sum(1, 2, 3, 4));
printf("%d
", sum(1, 2, 3));
printf("%d
", sum(1, 2));
printf("%d
", sum(1));
}

明明可以通過在標準庫里加幾個函數就能解決的問題,一定要發明一個僵硬的語法,這就是C++17的Fold Expression不好的地方。我擔心C++20會加入更多花里胡哨的東西


c++已經徹底走上不歸路了。這麼搞法遲早把編譯器玩死。。。還不如重新設計一門語言 或者直接用dlang go 什麼的了


什麼?C++還在更新?C++++都十年了,為什麼還要更新C++。

(逃


推薦閱讀:

剛學完c++primer的前18章,為了準備春招,現在是刷leetcode 更好,還是做些小項目?
學習 OpenGL 用哪個版本好?
如何理解 C++ 中的深拷貝和淺拷貝?
c/c++視頻教程哪個比較好? 能學下去的?
做遊戲與搞圖形學有什麼聯繫?

TAG:C |