VS2010對c++11的支援情況驗證
目前僅僅測試工作中 使用的比較多的:
智慧指標
shared_ptr
#include <memory> std::shared_ptr<A> a(new A);
----支援! 同時也支援 make_shared
weak_ptr
----支援,畢竟這是個給shared_ptr打輔助的指標模板
unique_prt
----支援! ,但不支援make_unique,這也正常,畢竟這是C++14的語法了。
綜合來看,可以在VS2010裡自有的使用智慧指標了。
auto型別自推導
vector<int> v_ints; v_ints.push_back(1); v_ints.push_back(2); auto it = v_ints.cbegin(); std::cout << *it <<std::endl; auto a = make_shared<A>(); auto b = a;
------支援!
lambda表示式
Constructs a closure: an unnamed function object capable of capturing variables in scope.
c++11中有以下三種語法:
[ captures ] ( params ) -> ret_type { body } (1)
[ captures ] ( params ) { body } (2)
[ captures ] { body } (3)
理論上都是第一種語法的簡化版,根據需要使用,
閉包是帶有上下文的函式。說白了,就是有狀態的函式
函式是程式碼, 狀態是一組變數 ,將程式碼和一組變數捆綁 (bind) , 就形成了閉包。
C++中實現閉包的三種方式
- 過載 operator()
因為閉包是一個函式+一個狀態, 這個狀態通過 隱含的 this 指標傳入. 所以 閉包必然是一個函式物件. 因為成員變數就是極好的用於儲存狀態的工具, 因此實現 operator() 運算子過載, 該類的物件就能作為閉包使用. 預設傳入的 this 指標提供了訪問成員變數的途徑.(事實上, lambda 和 bind 的原理都是這個.)
class MyFunctor { public: MyFunctor(float f) : round(f) {} int operator()(float f) { return f + round; } private: float round; }; float round = 0.5; MyFunctor f(round);
lambda表示式
float round = 0.5; auto f = [=](float f) { return f + round; }
C++11裡面的lambda就是閉包的實現。
boost::bind/std::bind
int boost_func(float f, float round) { return f + round; } float round = 0.5; boost::function<int(float)> f = boost::bind(boost_func, _1, round);
closure的狀態特指其執行的上下文。 closure將存貯它執行時需要的上下文,從而保證在closure建立時的上下文可以在closure執行時依然有效。
比如round就是closure的上下文。儲存上下文的這一特點通常被稱作“capture”或者是”bind”。 capture可以自己寫,比如MyFuctor f(round); 也可以用boost::bind。
vs2010測試:
int make_i = 3;
auto f = [=](int x){
std::cout << x << make_i << '\n';
};//這裡的;不能省略
f(make_i);
------- 支援!
支援匿名錶達式 ,則意味著閉包的支援,在C++裡,閉包不是那麼出名,畢竟這個概念是前端JS造出來的。但是清楚lambda表示式,我們可以精簡程式碼,後面有計劃補充學習記錄。可以先參考這裡。
for_each
Possible implementation
template<class InputIt, class UnaryFunction>
UnaryFunction for_each(InputIt first, InputIt last, UnaryFunction f)
{
for (; first != last; ++first) {
f(*first);
}
return f;
}
迴圈遍歷所有元素,使用f函式,對所有元素(迭代器)進行處理。
測試 for_each 裡的lambda表示式
#include <algorithm>
for_each(v_ints.begin(),v_ints.end(),[](int val){
cout << val << endl;
});
------ 支援!
Range-based for loop
vector<int> v_ints;
v_ints.push_back(1);
v_ints.push_back(2);
for (const int& i : v_ints) // access by const reference
std::cout << i << ' ';
std::cout << '\n';
編譯出錯。
----不支援 !
正則表示式
測試:
std::string fnamesstring[] = {"foo.txt", "bar.txt", "baz.dat", "zoidberg"};
vector<string> fnames(fnamesstring,fnamesstring+4);
std::regex txt_regex("[a-z]+\\.txt");
for_each(fnames.begin(),fnames.end(),[&](const string &fname){
std::cout << fname << ": " << std::regex_match(fname, txt_regex) << '\n';
} );
-------支援!
bind函式模板
The function template bind generates a forwarding call wrapper for f. Calling this wrapper is equivalent to invoking f with some of its arguments bound to args.
---- 函式模板繫結為f生成一個轉發呼叫包裝器。呼叫這個包裝器等價於呼叫f並將它的一些引數繫結到args。(機器翻譯很感人)
個人理解,bind函式模板,可以更大範圍的使用某些函式,比如巢狀繫結 子表示式函式,繫結類成員函式,甚至類的成員變數。
驗證程式碼:
#include <functional>
void f(int n1 ,int n2,int n3 ,int n4 ,int n5){
cout << n1 <<" "<< n2 <<" "<<n3 <<" "<<n4<<" "<<n5<<'\n';
}
using namespace std::placeholders;
void f(int n1 ,int n2,int n3 ,int n4 ,int n5);
auto b = bind(f,2,_1,_2,4,5);
b(100,200);
-------支援!
其他
vector<int> v_ints = {1,2,3,4,5,6,2,4,3};
vs2010不支援這樣初始化
可行的修改方案:
int ints[] = {1,2,3,4,5,6,2,4,3};
vector<int> v_ints(ints,ints+9);