【现代程序设计】【homework-07】
C++11 中值得關(guān)注的幾大變化
?
?
1.Lambda 表達(dá)式
Lambda表達(dá)式來源于函數(shù)式編程,說白就了就是在使用的地方定義函數(shù),有的語言叫“閉包”,如果 lambda 函數(shù)沒有傳回值(例如 void ),其回返類型可被完全忽略。 定義在與 lambda 函數(shù)相同作用域的變量參考也可以被使用。這種的變量集合一般被稱作 closure(閉包)。表達(dá)式的簡單語法如下
?
char s[]="Hello World!"; int Uppercase = 0; //modified by the lambda for_each(s, s+sizeof(s), [&Uppercase] (char c) { if (isupper(c)) Uppercase++; }); cout << Uppercase << " uppercase letters in: " << s <<endl; View Code在傳統(tǒng)的STL中for_each()
這個玩意最后那個參數(shù)需要一個“函數(shù)對象”,所謂函數(shù)對象,其實是一個class,這個class重載了operator(),于是這個對象可以像函數(shù)的式樣的使用。實現(xiàn)一個函數(shù)對象并不容易,需要使用template,比如下面這個例子就是函數(shù)對象的簡單例子(實際的實現(xiàn)遠(yuǎn)比這個復(fù)雜):
?
template <class T> class less { public: bool operator()(const T&l, const T&r)const { return l < r; } }; View Code?
所以,C++引入Lambda的最主要原因就是1)可以定義匿名函數(shù),2)編譯器會把其轉(zhuǎn)成函數(shù)對象。相信你會和我一樣,會疑問為什么以前STL中的ptr_fun()這個函數(shù)對象不能用?(ptr_fun()就是把一個自然函數(shù)轉(zhuǎn)成函數(shù)對象的)。原因是,ptr_fun() 的局限是其接收的自然函數(shù)只能有1或2個參數(shù)。
那么,除了方便外,為什么一定要使用Lambda呢?它比傳統(tǒng)的函數(shù)或是函數(shù)對象有什么好處呢?我個人所理解的是,這種函數(shù)之年以叫“閉包”,就是因為其限制了別人的訪問,更私有。也可以認(rèn)為他是一次性的方法。Lambda表達(dá)式應(yīng)該是簡潔的,極私有的,為了更易的代碼和更方便的編程。
?
2.自動類型推導(dǎo) auto
在在這一節(jié)中,原文主要介紹了兩個關(guān)鍵字 auto 和 deltype,示例如下
?
auto x=0; //x has type int because 0 is int auto c='a'; //char auto d=0.5; //double auto national_debt=14400000000000LL;//long longauto 最大的好處就是讓代碼簡潔,尤其是那些模板類的聲明,比如:STL中的容器的迭代子類型。
vector<int>::const_iterator ci = vi.begin();可以變成:
auto ci = vi.begin();模板這個特性讓C++的代碼變得很難讀,不信你可以看看STL的源碼,那是一個亂啊。使用auto必需一個初始化值,編譯器可以通過這個初始化值推導(dǎo)出類型。因為auto是來簡化模板類引入的代碼難讀的問題,如上面的示例,iteration這種類型就最適合用auto的,但是,我們不應(yīng)該把其濫用。
比如下面的代碼的可讀性就降低了。因為,我不知道ProcessData返回什么?int? bool? 還是對象?或是別的什么?這讓你后面的程序不知道怎么做。
?
auto obj = ProcessData(someVariables);但是下面的程序就沒有問題,因為pObject的型別在后面的new中有了。
?
auto pObject = new SomeType<OtherType>::SomeOtherType();?
?
3.自動化推導(dǎo) decltype
?
關(guān)于?decltype?是一個操作符,其可以評估括號內(nèi)表達(dá)式的類型,其規(guī)則如下:
原文給出的示例如下,我們可以看到,這個讓的確我們的定義變量省了很多事。
| 1 2 3 | const vector<int> vi; typedef decltype (vi.begin()) CIT; CIT another_const_iterator; |
還有一個適合的用法是用來typedef函數(shù)指針,也會省很多事。比如:
?
decltype(&myfunc) pfunc = 0; ?? typedef decltype(&A::func1) type; 4.auto 和 decltype 的差別和關(guān)系Wikipedia 上是這么說的(關(guān)于decltype的規(guī)則見上)
#include <vector> ?? int main() { ????const std::vector<int> v(1); ????auto a = v[0];??????? // a 的類型是 int ????decltype(v[0]) b = 1; // b 的類型是 const int&, 因為函數(shù)的返回類型是 ??????????????????????????// std::vector<int>::operator[](size_type) const ????auto c = 0;?????????? // c 的類型是 int ????auto d = c;?????????? // d 的類型是 int ????decltype(c) e;??????? // e 的類型是 int, 因為 c 的類型是int ????decltype((c)) f = c;? // f 的類型是 int&, 因為 (c) 是左值 ????decltype(0) g;??????? // g 的類型是 int, 因為 0 是右值 } 如果auto 和 decltype 在一起使用會是什么樣子?能看下面的示例,下面這個示例也是引入decltype的一個原因——讓C++有能力寫一個 “ forwardingfunction?模板”, template< typename LHS, typename RHS> ??auto AddingFunc(const LHS &lhs, const RHS &rhs) -> decltype(lhs+rhs) {return lhs + rhs;} 這個函數(shù)模板看起來相當(dāng)費解,其用到了auto 和 decltype
來擴展了已有的模板技術(shù)的不足。怎么個不足呢?在上例中,我不知道AddingFunc會接收什么樣類型的對象,這兩個對象的 +
操作符返回的類型也不知道,老的模板函數(shù)無法定義AddingFunc返回值和這兩個對象相加后的返回值匹配,所以,你可以使用上述的這種定義。 5.統(tǒng)一的初始化語法
?
?
C/C++的初始化的方法比較,C++ 11 用大括號統(tǒng)一了這些初始化的方法。
?
比如:POD的類型。
?
| 1 2 | int arr[4]={0,1,2,3}; struct tm today={0}; |
?
關(guān)于POD相說兩句,所謂POD就是Plain Old Data,當(dāng)class/struct是極簡的(trivial)、屬于標(biāo)準(zhǔn)布局(standard-layout),以及他的所有非靜態(tài)(non-static)成員都是POD時,會被視為POD。如:
?
| 1 2 3 | struct A { int m; }; // POD struct B { ~B(); int m; }; // non-POD, compiler generated default ctor struct C { C() : m() {}; ~C(); int m; }; // non-POD, default-initialising m |
?
POD的初始化有點怪,比如上例,new A; 和new A(); 是不一樣的,對于其內(nèi)部的m,前者沒有被初始化,后者被初始化了(不同 的編譯器行為不一樣,VC++和GCC不一樣)。而非POD的初始化,則都會被初始化。
?
從這點可以看出,C/C++的初始化問題很奇怪,所以,在C++ 2011版中就做了統(tǒng)一。原文作者給出了如下的示例:
?
| 1 2 3 4 5 6 7 8 9 | C c {0,0}; //C++11 only. 相當(dāng)于: C c(0,0); ?? int* a = new int[3] { 1, 2, 0 }; /C++11 only ?? class X { ????int a[4]; ????public: ????????X() : a{1,2,3,4} {} //C++11, member array initializer }; |
?
容器的初始化:
?
| 1 2 3 4 5 | // C++11 container initializer vector<string> vs={ "first", "second", "third"}; map singers = { {"Lady Gaga", "+1 (212) 555-7890"}, {"Beyonce Knowles", "+1 (212) 555-0987"}}; |
?
還支持像Java一樣的成員初始化:
?
| 1 2 3 4 5 6 | class C { ???int a=7; //C++11 only ?public: ???C(); }; |
?
轉(zhuǎn)載于:https://www.cnblogs.com/lightz/p/3417006.html
總結(jié)
以上是生活随笔為你收集整理的【现代程序设计】【homework-07】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: asp.net模态窗口返回值
- 下一篇: 奇怪的 加号