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

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

正則 param 所有 簡化 turn 推導 variables 閉包 ret

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

智能指針

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

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