C++ 语法再加强:C++0x
目前一般所使用的C++语法标准,实际上大部分应该都是俗称C++98 / C++03的ISO/IEC 14882:1998、ISO/IEC 14882:2003;其中C++03主要是针对C ++98做部分修正,变化并不大(微软VC++ team的说法:C++03只是C++98的「Service pack」)。那C++有打算再有追加新功能吗?实际上,目前也有还在规画中、没有正式定案的C++0x草案了!(详细可以参考维基百科上的C++ / C++0x的条目)
而随着新版GCC(4.4/4.5)和Visual Studio 2010的顶出,程序开发者也可以开始使用C++0x里的部分新功能了!不过由于实际上C++0x是还没正式定案的标准,所以其实不管是最新的GCC或Visual C++ 2010,也都还没有能完全支援C++0x的全部功能;实际上C++0x的规格也还在变动中,像concepts就被废掉了。
Heresy这一篇,主要会是以Microsoft Visual C++ 2010为主,介绍一些新的C++0x的语法;而GCC不同版本对C++0x的支援性,则建议可以参考官方的《C++ 0x Support in GCC》一文(用g++编译时需加上「-std=c++0x」这个参数)。
以Visual C++ 2010来说,他的新功能可以参考《What's New in Visual C++ 2010》,而C++0x的部分则可以参考VC++的team blog的《C++0x Core Language Features In VC10: The Table》一文;整体来说,VC++ 2010的C++0x的新功能主要包括了六部份:
auto:《C++0x: auto和decltype》[ MSDN ]
自动根据initialization expression来判断变量的型别,可以用来简化较复杂的型别的变量的声明;另外,也可以搭配新的decltype和lambda expression来做更多的应用。
下面就是一个简单的范例。在编写程序的时候,如果直接用「auto」来取代「map>::iterator」的话,就可以少打不少字。
- map< int ,list< string >>::iterator i = m.begin();
- auto i = m.begin();
decltype:《C++0x: auto和decltype》[ MSDN ]
decltype是用来指定变量的型别的(Type Specifier),不过他所声明的变量型别则是根据现有的变量、或是函式来做判断。而如果搭配auto使用的话,可以更方便地编写template function。
下方是一个简单的范例,透过这样的decltype写法,可以声明出一个和a同型别的变量b。
- int a;
- decltype( a ) b;
Lambda Expressions:《C++0x:Lambda expression》[ MSDN ]
Lambda expression 基本上算是「匿名函式(anonymous function)」,他可以快速地建立一个没有名称的function object,避免掉function object 要定义出一个class / struct 的繁琐工作。
他的语法可以参考《Lambda Expression Syntax》一文,而他比较基本的形式大致会是像下方的样子;他传入的参数是一个int、而回传值的型别(-> int)也是int:
- [] ( int x ) -> int
- {
- return x * x;
- }
下面是一个在使用for_each()时,使用lambda expression和function object的对照;在这种情况下使用lambda expression的话,程序码可以简化许多(不用定义出LambdaFunctor这个class):
使用function object
- class LambdaFunctor
- {
- public :
- void operator ()( int n) const {
- cout << n << " ";
- }
- };
- int main() {
- vector< int > v;
- for ( int i = 0; i < 10; ++i )
- v.push_back(i);
- for_each( v.begin(), v.end(), LambdaFunctor() );
- cout << endl;
- }
使用lambda expression
- int main() {
- vector< int > v;
- for ( int i = 0; i < 10; ++i)
- v.push_back(i);
- for_each(v.begin(), v.end(), []( int n) { cout << n << " "; } );
- cout << endl;
- }
Rvalue Reference:[ MSDN ]
这部分主要要先搞清楚C++里的Lvalues ??(left value)和Rvalues ??(right value)的意义了。而RValue reference主要则是可以用来实作所谓的「move semantics」和「perfect forwarding」了~
static_assert:《C++0x:static_assert和nullptr》[ MSDN ]
这个功能可以让编译器在编译时取做一些条件判断,并且让编译失败、并且显示自定义的错误信息。
下面是一个简单的范例:
- static_assert( sizeof ( void *) == 4, " 64bit is not supported. ");
nullptr:《C++0x:static_assert和nullptr》[ MSDN ]
nullptr是一个新的关键字,用来代表NULL指针的值;而本来在C++03 / C99里,这个角色是由0来做的(NULL实际上是define成0的macro),但是这样的缺点是无法区分0和NULL指针,在有的时后会产生overloaded function无法判断的问题。所以在C++0x里另外定义了nullptr,来和0做区隔。
而这边只是先针对这些新的功能做一些简单的介绍,之后会在针对一些功能,做更完整的介绍。
另外,《Visual Studio 2010 Released》一文有大致条列出Visual Studio 2010的新功能,对于Visual Studio 2010的其他部分有兴趣的,建议可以参考看看。
- 评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)
-
