Concepts and Rvalue Reference : C++0x will come C++0x马上就要出来了。目前已经有许多提议已经大致成型,下面是最有可能出现在C++0x标准中的几个提议: 一、Concepts Concept是BS极力要加入的一个新特性,用来对模板实例进行限制。例如 template<typename T>T max(T a, T b){ return a<b?b:a;} typename关键字允许T是任何实例,但是max的代码却对T有隐含的限制:T必须能够用“<”进行比较。 再例如 template<typename InputIterator>InputIterator advance(InputIterator iter, size_t n){ //...} InputIterator必须能够进行++操作。而考虑到advance对不同iterator的优化,可能需要iter+n的操作。 为了让编译器有效检查泛型参数的实例类型,加入Concept特性。 声明一个Concept: auto concept LessThanCompareable<typename T>{ bool operator < (T, T); // 必须存在该函数}; auto关键字表示对运算符重载进行更广义的匹配,例如T::operator(const T&)也被认为符合上面的Concept template<LessThanCompareable T>T max(T a, T b){ return a<b?b:a;} 或者使用where从句 template<typename T>T max(T a, T b)where LessThanCompareable<T>{ return a<b?b:a;} where从句可以对多个参数进行联合检查:auto concept Convertible<typename U, typename S>{ operator U (S);}; template<typename U, typename S>U conv(S src)where Convertible<U, S>{ return src;} 对于Iterator,可以定义如下概念: auto concept IteratorInterface<typename Iter>{ // 标准迭代器的5个关联类型 typename value_type; typename reference; typename pointer; typename difference_type; typename iterator_category; // 相关标准操作 reference operator*(const Iter&); // 解引用}; concept MemberCheck<typename T>{ T::T(); // 存在默认构造 T::T(const T&); //存在拷贝构造 T::~T(); // 存在析构 T::operator = (const T&); // 存在赋值运算符}; auto concept InputIterator<typename Iter>{ where MemberCheck<Iter> where IteratorInterface<Iter> // 或者where MemberCheck<Iter> && IteratorInterface<Iter> Iter& operator++(Iter&); Iter operator++(Iter&, int);}; concept ForwardIterator<typename Iter> : InputIterator<Iter>{}; auto concept BidirectionalIterator<typename Iter> : ForwardIterator<Iter>{ Iter& operator--(Iter&); Iter operator--(Iter&, int);}; auto concept RandomAccessIterator<typename Iter> : BidirectionalIterator<Iter>{ Iter& operator+(Iter&, int); Iter& operator-(Iter&, int);}; iterator_category其实已经可以不需要了。 还可以使用concept_map对类型进行关联映射: concept_map InputIterator<char*> { typedef char value_type; typedef char& reference; typedef char* pointer; typedef std::ptrdiff_t difference type; //..}; 这样,指针就自动拥有标准迭代器所具有的所有关联类型,iterator_traits可以寿终正寝了。 二、Rvalue Reference C++的引用属于lvalue const reference,它与Java的引用不同: C++:Object obj1, obj2;Object& robj = obj1; // robj=>obj1robj = obj2; // robj.operator=(obj2); robj=>obj1 ! Java:Object obj1 = new Object();Object obj2 = new Object();Object robj = obj1; // robj=>obj1robj = obj2; // robj=>obj2 ! C++的lvalue const reference不能引用non-const rvalue: int &r = 10; // 错int a = 10;int &r = a; // ok, r=>aint b = 11;r = b; // a = b, r=>a, b被解释为lvalue而非non-const rvalue void func(int &); //#1void func(const int &); //#2func(10); // #2 const rvaluefunc(*new int(10)); // #1 lvalue C++0x将引入新的引用类型:Rvalue Reference: int &&rr = 0; // rr=>0 non-const rvalue ref可以引用const rvalueint a = 10;rr = a; // rr=>rvalue(a)=10int b = 11;int &r = b; // r=>brr = r; // rr=>rvalue(r)=rvalue(b)=11, a=10(没有改变) Object &&rr = Object(); // 允许引用临时对象Object &r = Object(); // 错误。 两种引用的组合的标准转换: A& & = A& A的引用的引用转换为引用A& && = A& A的引用的rvalue引用转换为引用A&& & = A& A的rvalue引用的引用转换为引用A&& && = A&& A的rvalue引用的rvalue引用转换为rvalue引用 rvalue reference导致新增加两种重要的成员函数:移动构造和移动赋值 class string{private: char * p;public: string(const string &str) // 拷贝构造 copy-constructor { p = new char[strlen(str.p)+1]; strcpy(p, str.p); } string& operator = (const string &str) // 拷贝赋值 copy-assignment { p = new char[strlen(str.p)+1]; strcpy(p, str.p); return *this; } string(string &&str) // 移动构造 move-constructor { p = str.p; } string& operator = (string &&str) // 移动赋值 move-assignment { p = str.p; return *this; }}; 为什么string(const string &str)不能直接将str.p赋值给p?因为str具有const属性,无法将const var赋值给non-const var。为什么不将string(const string &str)写为string(string &str),operator=(const string &str)写为operator=(string &str)?因为后者不接受临时对象等rvalue表达式为参数,(string &&str)接受non-const rvalue,因此无法用(string &str)代替(string &&str)。 对于下面的交换算法: void swap(string &a, string &b){ string t = a; a = b; b = t;} 根据目前标准只能使用拷贝构造和拷贝赋值来编译。到了C++0x,由于增加了移动构造和移动赋值,因此效率可以大大提高!(注:a和b为lvalue,根据目前标准,可以转换为rvalue。See ISO/IEC 14882 4.1 Lvalue-to-rvalue conversion) 三、其他改进 list<vector<int>> 中“>>”可以被正确接受 增加auto声明。下面的代码for(std::vector<my_element_type>::iterator it=v.begin(); it!=v.end(); ++it)可以写为for(auto it=v.begin(); it!=v.end(); ++it)auto声明的变量,其类型可以由编译器通过初始值判断得出。 增加Delegating Constructors特性:class object{public: object() : _i(0), _d(0.0) {} object(int i) : _i(i), _d(0.0) {} object(double d) : _i(0), _d(d) {} object(int i, double d) : _i(i), _d(d) {}};其初始化列表写起来繁琐而容易出错。新特性允许如下初始化:class object{public: object() : object(0, 0.0) {} // 用object(int,double)初始化 object(int i) : object(i, 0.0) {} // 用object(int,double)初始化 object(double d) : object(0, d) {} // 用object(int,double)初始化 object(int i, double d) : _i(i), _d(d) {}}; 还增加了诸如weak_ptr等特性。以上特性是最后可能加入新标准的几个,拿出来给大家看看。

评论