C++0xの規格はほぼ固まり、もはや変更されることはない。恐らく、このまま規格制定されるものと思われる。さて、今C++の主要なコンパイラーを上げるとすると、gccとclangをおいて他にはない。MSVCはオモチャだ。右の両コンパイラーは、C++0xの新機能を実装し始めている。もちろん、まだ不完全な実装も多いが、とりあえず遊べる程度には実装できている機能も多いので、比較してみることにする。
gccのC++0xサポート状況は、以下のページに簡易な一覧がある。
C++0x Support in GCC - GNU Project - Free Software Foundation (FSF)
clangのC++サポート状況は、以下のページに簡易な一覧がある。
面白いことに、どちらか片方のコンパイラーでしか実装されていない機能が、結構ある。ここで少し比較をしてみようと思う。もちろん、細かく観ていくときりがないので、大きな機能だけを紹介する。また、どちらのコンパイラーでも実装されている機能は省く。実装されていない機能は紹介する。
gccしか実装していない機能は、以下の通りである。
初期化リスト
std::vector<int> v = { 1, 2, 3, 4, 5 } ; // 便利便利
lambda
std::string str("表示するよ:") ; // キャプチャもできるよ std::for_each( v.begin(), v.end(), [=](int i){ std::cout << str << i << std::endl ; } ) ;
ローカルクラスと無名クラスをテンプレート実引数に取る
template < typename T > void f(T) { } void g() { struct X { } ; std::vector<X> v ; // ローカルクラスはOK enum { e1 } ; f( e1 ) ; // 無名クラスもOK }
生文字列リテラル
char16_t const * ptr = uR"( ここには何でも書ける。 もちろん、\とかも書けるし、 この改行だって、ちゃんと改行として反映される。 ただし、\に続くuとUは使えないので注意。 "に続く(とか、)に続く"も書けない。 もちろん、連続しなければOK。 )" ;
unionの制限取っ払い
union U { int x ; double d ; // 普通のクラスは余裕で持てる。 std::string s ; // コンストラクターだって楽勝。 U() : s("initialize") { } // メンバー関数もOK。virtual関数はダメだけど void f() { } } ;
constexpr
constexpr int twice( int x ) { return x * 2 ; } template < int I > struct X { } ; X< twice(100) > x ; // X<200>
clangしか実装していない機能は、以下の通りである。
コンストラクターのデリゲート(丸投げ)
struct X { X( int i ) : X(i, 0) { } // 丸投げ X( int i1, int i2 ) { } } ;
非staticデータメンバーの宣言の初期化子
struct X { int m = 0 ; X() { } // mは0 X( int i ) : m(i) { } // mはi } ;
テンプレートエイリアス(エイリアス宣言も含む)
using A = int ; A a ; // int template < typename T > using B = T ; B<int> b ; // int template < typename T > using C = std::vector< T, CustomAllocator > ; C<int> c ; // std::vector< int, CustomAllocator >
まだどちらも実装していない機能
アトリビュート
[[]] int [[]] x ;
アライメント
struct X { int x ; double d ; } ; void f() { alignas(X) char a[100] ; // X型に要求されるアライメントを指定 alignas(16) char b[100] ; // 16バイトアライメントを指定 alignas(X, 4, float) char c[100] ; // X型と4バイトとfloat型とで、一番強いアライメント要求を指定 alignof(int) ; // int型に要求されるアライメント(定数式) }
コンストラクターの継承
struct Base { Base() { } Base(int) { } Base(double) { } } ; struct Derived : Base { // コンストラクターを継承 using Base::Base ; } ; Derived d(0) ; // OK
ユーザー定義リテラル
void operator "" _owata ( char16_t *, std::size_t ) { } int main() { uR"(  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄」 ―――――――――――――‐┬┘ | ____.____ | | | | | | | ∧_∧ | | | |( ´∀`)つ ミ | | |/ ⊃ ノ | |  ̄ ̄ ̄ ̄' ̄ ̄ ̄ ̄ | ミ ユーザー定義リテラル )"_owata ; }
No comments:
Post a Comment