私は次のコードを持っています(大きなコードチャンクで申し訳ありませんが、これ以上絞り込むことはできませんでした)
template <bool B>
struct enable_if_c {
typedef void type;
};
template <>
struct enable_if_c<false> {};
template <class Cond>
struct enable_if : public enable_if_c<Cond::value> {};
template <typename X>
struct Base { enum { value = 1 }; };
template <typename X, typename Y=Base<X>, typename Z=void>
struct Foo;
template <typename X>
struct Foo<X, Base<X>, void> { enum { value = 0 }; };
template <typename X, typename Y>
struct Foo<X, Y, typename enable_if<Y>::type > { enum { value = 1 }; };
int main(int, char**) {
Foo<int> foo;
}
しかし、gcc (v4.3) でのコンパイルに失敗します。
foo.cc: In function ‘int main(int, char**)’:
foo.cc:33: error: ambiguous class template instantiation for ‘struct Foo<int, Base<int>, void>’
foo.cc:24: error: candidates are: struct Foo<X, Base<X>, void>
foo.cc:27: error: struct Foo<X, Y, typename enable_if<Y>::type>
foo.cc:33: error: aggregate ‘Foo<int, Base<int>, void> foo’ has incomplete type and cannot be defined
OK、あいまいです。しかし、特殊化を使用する場合、ほとんどの場合あいまいになるため、それが問題になるとは思っていませんでした。ただし、このエラーはクラスをenable_if<...>
で使用した場合にのみトリガーされます。次のようなクラスに置き換えれば問題ありません。
template <typename X, typename Y>
struct Foo<X, Y, void > { enum { value = 2 }; };
このクラスはあいまいさを引き起こさないのに、他のクラスはなぜあいまいさを引き起こさないのですか? 真の::値を持つクラスの場合、2つは同じことではありませんか? とにかく、私が間違っていることについてのヒントは大歓迎です。
答えてくれてありがとう、私の本当の問題(コンパイラに最初の専門分野を選択させるため)は、私が望むように動作するように見えるものを置き換えるstruct Foo<X, Base<X>, void>
ことで解決されましstruct Foo<X, Base<X>, typename enable_if< Base<X> >::type >
た。