3

http://en.wikipedia.org/wiki/Substitution_failure_is_not_an_error

#include <iostream>

template <typename T>
struct has_typedef_foobar {
    // Types "yes" and "no" are guaranteed to have different sizes,
    // specifically sizeof(yes) == 1 and sizeof(no) == 2.
    typedef char yes[1];
    typedef char no[2];

    template <typename C>
    static yes& test(typename C::foobar*);

    template <typename>
    static no& test(...);

    // If the "sizeof" the result of calling test<T>(0) would be equal to the sizeof(yes),
    // the first overload worked and T has a nested type named foobar.
    static const bool value = sizeof(test<T>(0)) == sizeof(yes);
};

struct foo {    
    typedef float foobar;
};

int main() {
    std::cout << std::boolalpha;
    std::cout << has_typedef_foobar<int>::value << std::endl;
    std::cout << has_typedef_foobar<foo>::value << std::endl;
}

上記の例は SFAINE を示しています。

  • ここで、sizeof(yes)==1 と sizeof(no)==2 の理由がわかりません。
  • テストは静的関数であるため、テスト関数の定義もあるはずですが、ここのコードはテスト関数を定義しなくても問題なくコンパイルされます
4

1 に答える 1

4

1)sizeof(char)は 1 に等しいと定義されています。yesは 1 文字の配列の typedef であるため、そのサイズは 1 でなければなりません。同様に、noは 2 文字の配列の typedef なので、そのサイズは2 * sizeof(char)である 2 でなければなりません。

2) 関数testは呼び出されないため、定義は不要です。sizeof演算子はコンパイル時の操作であるため、コンパイラは、指定されたテンプレート パラメーターを使用して test のインスタンス化の戻り値の型のサイズを調べるだけです。呼び出されないため、定義は不要です。これは、クラスをコピー構築不可能にするために、非定義のプライベート コピー コンストラクターを作成するのと同様です。

于 2013-01-08T08:17:11.320 に答える