2012-06-28 12 views
5

私は、インスタンス化がtypedef 'であるときにクラステンプレートの静的アサーションがトリガされないことに気付きました。typedefでstatic_assertをトリガーする必要がありますか?

#include <type_traits> 

template <typename T> 
struct test_assert 
{ 
    static_assert(std::is_same< T, int >::value, "should fail"); 
}; 

typedef test_assert<float> t; 

このコードはエラーなしでコンパイルされます。私はインスタンスを作成しようとすると、アサーションは失敗します。

t obj; // error: static assertion failed: "should fail" 

を最後に、私はfalseと条件を置き換えた場合、アサーションは私はクラステンプレートインスタンス化していない場合でも失敗:

template <typename T> 
struct test_assert 
{ 
    static_assert(false, "always fails"); 
}; 

gcc-4.5.1とgcc-4.7.0でこのコードを試しました。この動作は正常ですか?コンパイラは何時に静的アサーションを検証することになっていますか?私は2フェーズのルックアップが関係していると思いますが、typedefが第2フェーズをトリガーすべきではないでしょうか?

+0

+1。素晴らしい質問。 :-) – Nawaz

答えて

9

gcc-4.5.1とgcc-4.7.0でこのコードを試しました。この動作は正常ですか?

はい

何時にコンパイラが静的なアサーションを検証することになっていますか?

これは興味深い質問です。インスタンス化中は、依存しない名前の第1フェーズルックアップと、テンプレート引数に依存するアサートの第2ルックアップフェーズとなります。

は、二相のルックアップが関与していると思いますが、typedefのトリガ は、第二段階ではないはず?

テンプレートは必要に応じてコンパイルされますが、typedefはテンプレートのエイリアスを作成してインスタンス化をトリガーしません。

template <typename T> class unique_ptr; 
typedef unique_ptr<int> int_unique_ptr; 

テンプレートのみが宣言され、それは唯一のタイプの別名を生成するように、それは、typedefのために十分で次のコードを検討します。反対に、タイプのオブジェクトを作成する場合は、テンプレートをインスタンス化する必要があります(必要に応じて、メンバー関数はインスタンス化されません)。

+0

ありがとう、これは私が考えたものです。テンプレートのメタプログラミングの数ヶ月で気付かなかったので、私は驚きました。実際、TMPでは 'typedef'は通常インスタンス化をトリガーする入れ子型にアクセスします。 –

+0

+1すばらしい答え! – Nawaz

関連する問題