译文

VC10中的C++0x特性 Part 1 (3) : Lambdas,auto,以及 static_assert

翻译:飘飘白云 | 2009-05-29 10:32:15 | 阅读558 | 来源

VC10中的C++0x特性 Part 1 (3) : Lambdas,auto,以及 static_assert

 

来源:vcblog 翻译:飘飘白云 kesalin@gmail.com

 

共三页: 第一页 第二页 本页

 

注意可选的 lambda 参数声明语法上包括:

( lambda-parameter-declaration-listopt ) mutableopt exception-specificationopt lambda-return-type-clauseopt

 

因此,如果你想使用 mutable   -> ReturnType,你需要在 lambda 导引符和它们之间插入空括号。

最后,因为 lambda 产生普通的函数对象,你可以在 tr1::function 中存储它们。

C:Temp>type tr1kitty.cpp

#include <algorithm>

#include <functional>

#include <iostream>

#include <ostream>

#include <vector>

using namespace std;

using namespace std::tr1;

 

void meow(const vector<int>& v, const function<void (int)>& f) {

    for_each(v.begin(), v.end(), f);

    cout << endl;

}

 

int main() {

    vector<int> v;

 

    for (int i = 0; i < 10; ++i) {

        v.push_back(i);

    }

 

    meow(v, [](int n) { cout << n << " "; });

    meow(v, [](int n) { cout << n * n << " "; });

 

    function<void (int)> g = [](int n) { cout << n * n * n << " "; };

 

    meow(v, g);

}

 

C:Temp>cl /EHsc /nologo /W4 tr1kitty.cpp > NUL && tr1kitty

0 1 2 3 4 5 6 7 8 9

0 1 4 9 16 25 36 49 64 81

0 1 8 27 64 125 216 343 512 729

 

 

auto


关键词 auto 是从 C++ 98 得来的,它在 C++ 98 中实际上并没起什么作用,但在 C++ 0x 中被重用于自动类型推导(automatic type deduction)。 在一个声明中使用 auto ,意味着“让它和初始化它的事物具有相同的类型”。你看:

 

C:Temp>type autocat.cpp

#include <iostream>

#include <map>

#include <ostream>

#include <regex>

#include <string>

using namespace std;

using namespace std::tr1;

 

int main() {

    map<string, string> m;

 

    const regex r("(\w+) (\w+)");

 

    for (string s; getline(cin, s); ) {

        smatch results;

 

        if (regex_match(s, results, r)) {

            m[results[1]] = results[2];

        }

    }

 

    for (auto i = m.begin(); i != m.end(); ++i) {

        cout << i->second << " are " << i->first << endl;

    }

}

 

C:Temp>cl /EHsc /nologo /W4 autocat.cpp > NUL && autocat

cute kittens

ugly puppies

evil goblins

^Z

kittens are cute

goblins are evil

puppies are ugly

 

map<string, string>::iterator,你近10年的恐怖统治终于到头了。


(注意:m.begin()返回 iterator,而不是 cosnt_iterator,因为 map 不是 const 属性的。C++ 0x cbegin() 允许你从一个 non-cosnt 容器中获得一个 const_iterator。)


lambdas and auto

 

先前我提到过在 tr1::functions 中存储 lambda 函数。但是如非必要请别这么做,因为 tr1::function 会增加一些开销。如果你想重用 lambda 函数,或只想给它命名的话,你可以使用 auto。这儿有一个简洁的例子:

 

C:Temp>type autolambdakitty.cpp

#include <algorithm>

#include <iostream>

#include <ostream>

#include <vector>

using namespace std;

 

template <typename T, typename Predicate> void keep_if(vector<T>& v, Predicate pred) {

    auto notpred = [&](const T& t) {

        return !pred(t);

    };

 

    v.erase(remove_if(v.begin(), v.end(), notpred), v.end());

}

 

template <typename Container> void print(const Container& c) {

    for_each(c.begin(), c.end(), [](const typename Container::value_type& e) { cout << e << " "; });

    cout << endl;

}

 

int main() {

    vector<int> a;

 

    for (int i = 0; i < 100; ++i) {

        a.push_back(i);

    }

 

    vector<int> b;

 

    for (int i = 100; i < 200; ++i) {

        b.push_back(i);

    }

 

    auto prime = [](const int n) -> bool {

        if (n < 2) {

            return false;

        }

 

        for (int i = 2; i <= n / i; ++i) {

            if (n % i == 0) {

                return false;

            }

        }

 

        return true;

    };

 

    keep_if(a, prime);

    keep_if(b, prime);

 

    print(a);

    print(b);

}

 

C:Temp>cl /EHsc /nologo /W4 autolambdakitty.cpp

autolambdakitty.cpp

 

C:Temp>autolambdakitty

2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97

101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199


notpred 是一个否定 lambda 函数,注意我们不能使用 C++ 98 <functional>中的 not1() 函数,因为那要求你的谓词函数继承unary_function,而 lambda 函数并不满足这个条件。


static_assert


static_assert 让你能够在触发编译器错误时使用定制的错误信息:

 

C:Temp>type staticfluffykitten.cpp

template <int N> struct Kitten {

    static_assert(N < 2, "Kitten<N> requires N < 2.");

};

 

int main() {

    Kitten<1> peppermint;

 

    Kitten<3> jazz;

}

 

C:Temp>cl /EHsc /nologo /W4 staticfluffykitten.cpp

staticfluffykitten.cpp

staticfluffykitten.cpp(2) : error C2338: Kitten<N> requires N < 2.

        staticfluffykitten.cpp(8) : see reference to class template instantiation 'Kitten<N>' being compiled

        with

        [

            N=3

        ]


如果你有任何疑问,我很乐意在评论中回答它们。


Stephan T. Lavavej

Visual C++ Libraries Developer

Published Tuesday, October 28, 2008 9:31 AM by vcblog

 

分享:

标签:C++0x,

添加评论