5

インスタンス化が行われると、クラス テンプレートの静的アサーションがトリガーされないことに気付きましたtypedef

#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 番目のフェーズをトリガーするべきではありませんか?

4

1 に答える 1

9

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

はい

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

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

2 フェーズのルックアップが関係していると思いますが、typedef が 2 番目のフェーズをトリガーするべきではありませんか?

テンプレートはオンデマンドでコンパイルされます。typedef はテンプレートのエイリアスを作成するだけで、インスタンス化はトリガーしません。次のコードを検討してください。

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

テンプレートは宣言されるだけですが、typedefは型のエイリアスを生成するだけなので、それで十分です。一方、型のオブジェクトを作成する場合は、テンプレートをインスタンス化する必要があります (これもオンデマンドで、メンバー関数はインスタンス化されません)。

于 2012-06-28T19:37:36.947 に答える