1. 程式人生 > >VS2010對c++11的支援情況驗證

VS2010對c++11的支援情況驗證

目前僅僅測試工作中 使用的比較多的:

智慧指標

  1. shared_ptr

    #include <memory>
    std::shared_ptr<A> a(new A);

    ----支援! 同時也支援 make_shared

  2. weak_ptr

    ----支援,畢竟這是個給shared_ptr打輔助的指標模板

  3. 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);