14

operator<<タイプに提供されているかどうかを確認する方法を見つけました。

template<class T> T& lvalue_of_type();
template<class T> T  rvalue_of_type();

template<class T>
struct is_printable
{
    template<class U> static char test(char(*)[sizeof(
        lvalue_of_type<std::ostream>() << rvalue_of_type<U>()
    )]);
    template<class U> static long test(...);

    enum { value = 1 == sizeof test<T>(0) };
    typedef boost::integral_constant<bool, value> type;
};

このトリックはよく知られていますか、それともメタプログラミングのノーベル賞を受賞したばかりですか?;)

編集:コードを理解しやすくし、2つのグローバル関数テンプレート宣言lvalue_of_typeとで適応しやすくしましrvalue_of_typeた。

4

2 に答える 2

7

それはよく知られているテクニックです、私は恐れています:-)

演算子で関数呼び出しを使用するとsizeof、もちろん、コンパイル時に引数の推定と関数の照合を実行するようにコンパイラーに指示されます。また、テンプレート関数を使用すると、コンパイラはテンプレートから具体的な関数もインスタンス化します。ただし、この式では関数呼び出しは生成されません。SFINAE SonoBuoniPDFで詳しく説明されています。

他のC++SFIN​​AEの例を確認してください。

于 2010-01-24T16:18:04.010 に答える
1

これは、2つのよく知られたトリックの組み合わせにすぎません。SFINAEは、「置換の失敗はエラーではない」と述べています。これはまさにあなたがしたことです。コンパイラが実際に実行せずにテンプレート引数を式に置き換えられるようにするために使用sizeofすることも一般的です。

ごめん :-)

于 2010-01-24T16:14:57.673 に答える