60

次のコードを検討してください。

#include <iostream>
#include <type_traits>

template <typename T>
struct A {
    int val = 0;

    template <class = typename std::enable_if<T::value>::type>
    A(int n) : val(n) {};
    A(...) { }

    /* ... */
};

struct YES { constexpr static bool value = true; };
struct NO { constexpr static bool value = false; };

int main() {
    A<YES> y(10);
    A<NO> n;
    std::cout << "YES: " << y.val << std::endl
              << "NO:  " << n.val << std::endl;
}

enable_if を使用して、一部の型のみにコンストラクター A::A(int) を選択的に定義したいと考えています。他のすべてのタイプには、デフォルトのコンストラクター A::A(...) があり、置換が失敗した場合のコンパイラーのデフォルトのケースになります。ただし、これは私にとって理にかなっていますコンパイラ(gccバージョン4.9.0 20130714)はまだ不平を言っています

sfinae.cpp: 'struct A' のインスタンス化: sfinae.cpp:19:11:
ここから必要 sfinae.cpp:9:5: エラー: 'type' という名前の型が
'struct std::enable_if'にありません
A(int n) : val(n) {};

コンストラクターでこのようなことは可能ですか? これは別のコンストラクター (コピーコンストラクターとムーブコンストラクター) で可能ですか?

4

3 に答える 3

53

クラステンプレートがインスタンス化されるときにその値を解決する必要があるため、これは単一のデフォルトのテンプレートパラメーターでは機能しないと思います。

コンストラクタ テンプレートのインスタンス化の時点まで置換を延期する必要があります。1 つの方法は、テンプレート パラメーターをデフォルトで T にし、コンストラクターに追加のダミー パラメーターを追加することです。

template<typename U = T>
A(int n, typename std::enable_if<U::value>::type* = 0) : val(n) { }
于 2013-07-24T19:03:23.420 に答える