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