如何評價 C++14 ?
謝謝邀請。我先發個大牛會議後的感想鏈接吧:The View from the C++ Standard meeting September 2013 Part 1 (C/C++ Cafe)
======================2014年2月26日更新============================
最近在準備畢業論文,所以現在有空來更新回答這個問題。正如 @vczh所說,這幾個是比較大的。我與同事一起閱讀探討過幾個提案,我把我負責的幾個說一下吧,沒有負責的就談一個。
第一個是Return type deduction for normal functions,參考鏈接是:Return type deduction for normal functions這一個提案其實在C++11的時候就提到了,但是由於當時投票的時候時間已經不夠了,這個提案也就順延了。這個提案的意義是加強了auto,如在函數上,可以不像11那樣,需要一個Trailing Return Type了。舉個例子吧在11中,你需要這樣:auto f(int a, int b) -&> decltype( a + b )
{
int i = a + b;
return i;
}
int main()
{
std::cout &<&< f(1,2) &<&< std::endl;
return 0;
}
然而在這個提案中,你就可以這樣了
auto f(int a, int b)
{
int i = a + b;
return i;
}
int main()
{
std::cout &<&< f(1,2) &<&< std::endl;
return 0;
}
也就是說,可以不要那個「尾巴」了。
而且在這個提案中,auto也可以用在模板中了,具體可以看提案。而對於這個提案,我們只在一個地方有疑問:auto sum(int i) {
if (i == 1)
return i; // return type deduced to int
else
return sum(i-1)+i; // ok to call it now
}
這裡,的確是這樣的。但是我們當時提出了一個疑問,如果我這裡的return statement是這樣的
auto sum(int i) {
if (i == 1)
return i; // return type deduced to int
else
return sum(i-1)+i + 0.0; // 這樣怎麼辦呢?
}
可能會說自動提升,但是這裡的提案說應該deduce to int,是根據這裡的i來判定的,但是我這裡加了0.0後,一切就變了。這一個當時我們給了C++標準委員會的Michael Wong,不過很遺憾,我後面走了,不知道答覆是什麼。
另外一個是:Heterogeneous lookup in associative containers。 鏈接是:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3465.pdf
這是一個有關Library的改進,是一個如果你沒有熟悉STL,絕對想不到竟然沒有的東西,因為我在拿到這個提案的時候,潛意識就是覺得以前竟然沒有?簡單的來說,由於map等關聯容器的內部數據結構和vector這樣的不一樣,所以你可以發現find等,在map中你是有對應的map成員函數來保證的,因為是平衡樹的查找,可以保證是log級別的複雜度。在這篇提案前,有一個函數方法叫equal_range,而對於這個查找匹配元素,以前的map等關聯容器只接受一個Key,而沒有自定義的比較函數。那麼如果沒有內置的operator &< 支持的話,你就只能使用std::equal_range來做了,但是很顯然這個複雜度比log級別的要高,所以這篇提案就建議為關聯容器的equal_range加上自定義比較函數的參數了,而自定義比較函數需要滿足的條件是:strict weak orderings。這個就是那什麼if ( x &< y ) { return true;} if ( y &< x ) {return false;}那一套,這個請參考C++標準庫那本書相關的介紹,肯定有這個說明。這裡面,還有一個提案是:make_unique。鏈接是:ISO/IEC JTC1/SC22/WG21
N3656
我負責看以及與同事分享的還有一篇提案:關於字元串Literal的值的。鏈接為:http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2013/n3642.pdf 這篇提案沒有特殊之處,主要是可以加入ms, s等東西,而對於這篇提案,我曾經提過一個反饋意見,為什麼不更加精確到皮秒,這對於一些科學研究來說,是需要這麼精確的。
最後說一篇不是我負責的,但是引起了我們激烈討論的一篇提案:放鬆constexpr的限定。鏈接為:Relaxing constraints on constexpr functions
這篇提案可謂是深得標準委員會人員的心,不可否認,這篇提案對於普通開發人員無疑是福音,因為可以再次提高性能。但是對於編譯器開發人員簡直是噩夢的一篇提案。說實話,在C++11的所有特性中,constexpr絕對是一個很難實現的特性,我不能透露ibm編譯器如何實現的,感興趣的可以去參看GCC或者Clang的實現。直到現在,Visual C++的實現constexpr都是Partial的狀態。眾所周至,constexpr有一些限定,比如只能返回一條語句等,即使這樣,編譯器做起來都是很頭痛的一件事情。這篇提案簡直逆天了,要去掉這些條件,還可以加入if,for什麼的了,,具體的可以參看提案內容。我只能說簡直喪心病狂,完全不管編譯器開發者的死活。當時我們激烈討論了到底怎麼實現的,但是也沒有討論出來什麼。但就是這篇提案,標準委員會舉雙手雙腳贊成,而且還說有實現的先例:D語言。我也不知道該說什麼了。其餘還有一些比如泛型Lambda等,我這裡就沒有提了,因為我沒有看這些提案,我就不說了。
最後總結一下就是,C++14可以稱為更加完美的C++11,這是我的觀點。我覺得這些提案本就應該在C++11出現,但是卻由於各種因素才拖到C++14中了。 C++的確變得更加複雜了,但是對於今天學習C++的人來說是更幸福的,少了很多奇淫技巧,多了更多照顧開發者的東西。
======================2015年7月15日更新==============================似乎這個一年前寫的答案又被翻出來了,然後我就補一下去年留下的那個疑問的回復。auto sum(int i) {
if (i == 1)
return i; // return type deduced to int
else
return sum(i-1)+i + 0.0; // 這樣怎麼辦呢?
}
對於這個,是不允許的,編譯器會報錯,不會類型轉換。
對比C++11,C++14改變比較大的有
Concept-lite
模板lambda表達式
函數返回decltype(auto)
第一個是給寫庫用的那些對模板不熟悉的可以直接跳過,對於熟悉模板的人來說,Concept-lite對於用戶唯一的好處估計就是錯誤信息比較容易看懂了。因為只是lite,所以其實沒太大用處。
模板lambda表達式可以讓你少寫巨長無比的類型,decltype(auto)也是
=====================================
看了 @藍色 貼的文章,我覺得C++永遠的跟正則表達式構造的詞法分析器說拜拜了,連詞法分析也只能跟語法分析和語義分析一起做了,好蛋疼……
整體來說,除了Concept Lite外,C++14是C++11的補丁。Concept Lite是整個模板系統的補丁。-----------------關於constexpr, 233333, 沒有指針的時候還好說,給你來點指針,基本上就跪了。理論上constexpr的極限是:但凡每次運行都固定的東西那就一定能推斷的出來。
熟習使用C++11的人看到C++14都會欣喜若狂,但是壓根連C++本身都沒太搞明白的,估計看到C++14都是一個反映:這什麼玩意,關我啥事。使用其他腳本語言的看到C++14會想,C++再怎麼學習我們腳本也做不到我們腳本這樣好,反而把自己搞的巨複雜,一門越來越臃腫的語言。
好吧,我是全棧,主攻C++。首先你得承認C++11是好的改進,我才能繼續誇14,否則14就沒有了存在的基礎。比如你用nghttp2的C++庫,Lambda的使用會讓你非常銷魂,asio可能得使用很長時間才能感覺到lambda的好,但是到應用層級,你在使用lambda做回調的時候就知道他能多大程度的有益於工程。11讓我們能夠傳lambda(在11出來之前我就有使用boost的lambda,11出來後我也使用golang的coroutine,都是一個道理),但是傳的時候我就發現我不能捕獲一個之前沒有定義的常量,而我是有這個需求的,因為非同步調用的產生的位置點本身就是一個變數。
還有可以文本的二進位,還可以』分隔,對於我們這種底層程序員簡直是福音有木有。但是關聯容器的異構查找還有元編程的改進,雖然不關我啥事,我也用不到,就像吃瓜群眾一樣,不知道你們在搞啥。但是我知道寫庫的人會因此收益。
還有auto的出現,我感覺是C++11中我使用最多的特性,然而返回值,你在設計一個系統架構的時候,有沒有遇到過我擦我實在是不想返回一個長長的map&
成員變數初始化,反正C++11的成員變數初始化對我的生活的改善巨大,但是就是union不能初始化,搞到我都不想用union了,C++14又說可以用了,您說說,我能不開心麽?
至於optional我就是吃瓜群眾了。返回bool我感覺挺好的,optional我也要檢查,我寧肯變數是隨即值也不希望變數為空。可能有人會喜歡?我想不出來,但是多年的經驗告訴我,這通常是因為我知識不夠,經驗不足。
我個人觀點:C++14主要是對lambda的補全和標準庫易用性的改進。關於lambda舉幾個例子:在C++11中:
std::shared_ptr&
auto f = [x] { std::cout &<&< (*x) &<&< std::endl; } // OK
std::unique_ptr&
auto g = [y] { std::cout &<&< (*y) &<&< std::endl; } // Error: std::unique_ptr is not copyable
auto h = [y] { std::cout &<&< (*y) &<&< std::endl; } // OK
auto i = [y] {...} // syntax error
auto j = [z = std::move(y)] { } // syntax error
用簡單的話來說明:C++11的lambda捕捉類對象時,要麼調用複製構造函數,要麼通過引用,而不管通過什麼手段,都不能讓lambda在捕捉類對象時調用其轉移構造函數。而且通過引用來捕捉上下文變數並不總是有效,比如下面這個例子:
std::function&
{
std::unique_ptr&
return [p] { return (*p)++; };
}
auto x = g(1);
x(); // Undefined behaviour
這一點導致std::unique_ptr的在非同步操作時的實用性大打折扣,如果我們需要讓用作非同步回調的lambda函數捕捉一個智能指針,我們只能使用std::shared_ptr。在C++14中,引入了 Lambda captures expressions,解決了這個問題
std::function&
{
std::unique_ptr&
return [p = std::move(p)] { return (*p)++; }; // OK in c++14
// [ ]
}
auto x = g(1);
std:;cout &<&< x() &<&< std::endl; // prints 1
std:;cout &<&< x() &<&< std::endl; // prints 2
......
除此之外,C++14也改進了STL的易用性,例如std::less&
template&
template&
template&
bool operator &< (const T lhs, const T rhs) { return lhs &< rhs; }
};
//Since C++14
template&<&> struct less&
template&
bool operator &< (const L lhs, const R rhs) { return lhs &< rhs; }
};
auto a = less&<&>();
a(1.2f, 0); //OK
auto b = less&
b(1.2f, 0); // Should cause compile error
在C++14中,對於std::less,std::greater等對void進行了特化,不光少敲了幾個字,還更通用了。
C++98/03: Traditional C++C++11/14: Modern C++Modern C++就是為了「新手友好」開發出來的新語言 用smart pointer換掉raw pointer 用container換掉內置數組向動態類型語言學習auto, decltype以上的改進使得Modern C++在面向類的編程範式裡邊無限向Java靠攏只用STL和primitive type(不含raw pointer raw array)拷貝控制可以全部使用合成實現,比Traditional C++不知道高到哪裡去了
不過貌似現在也沒有人寫純粹的Modern C++教程 兩個世代的東西混雜起來講確實就比較複雜了
哎,我特么連11都沒看完,這就到14了?!
C++的入門門檻越來越高,心智負擔越來越重,越來越不適合新手,而一門不能吸引新手的語言是沒有未來的。在我看來,C++標準委員會最應該做的事情不是在語言特性上搞花樣,而是應該大力增強應用開發庫/框架,避免大家一遍一遍的造輪子。這麼多年來,C++標準委員會在這方面幾乎無所作為。
個人認為規則越繁雜的語言越垃圾,就如同windows系統一樣不斷更新補丁遮蓋之前設計的不足,C++語法不如C簡潔,又沒有java等易用,兩面都不討好,我覺得當下最好是提供易用的標準庫,如同xcode,eclipse像樣的ide,還有操作系統直接大力支持,eclipse雖然支持c++但還是用c++自己實現環境比較好,本人一直感慨win下c++沒找到如同java canvas一樣好用的圖形api
推薦閱讀:
※【for(int i=10, j=1; i=j=0; i++, j--)()】將循環幾次?
※無編程基礎,跳過C直接學C++,壞處是學習難度陡峭,還是會有知識缺陷,還是二者都有?
※關於《深度探索C++對象模型》有一段話看不懂?
※輪子哥可以分享一下曾經是怎樣帶學生的嗎?
※cout 和 cin 的底層實現是怎樣的?
TAG:C |