SFINAEを使用してメソッドのオーバーロードを行うためには、どのルールを考慮する必要があるのかわかりません。私は知っているより多くのルールが関与するために縫い目が存在するので、問題で何度も実行されます。ですから、何度も何度も質問するのではなく、一般的な問題を解決するために簡単に説明できる一連のルールがあることを願っています。SFINAEのオーバーロードについて考慮する必要があるルール
私のスタート地点はここにあった:私のコードを変更し、
"the "constructor cannot be overloaded" problem can be solved by adding a dummy and defaulted template parameter (like , typename Z = void) to one of the constructors"
OK: Specializing class with SFINAE if a parameter pack is needed
コード1
class AA { public: using TRAIT = int; };
class BB { public: using TRAIT = float; };
template < typename T>
class Y
{
public:
template <typename U = T, typename V= typename std::enable_if< std::is_same< int, typename U::TRAIT>::value, int >::type>
Y() { std::cout << "First" << std::endl; }
template <typename U = T, typename V= typename std::enable_if< !std::is_same< int, typename U::TRAIT>::value, float >::type>
Y() { std::cout << "Second" << std::endl; }
};
error: 'template template Y::Y()' cannot be overloaded
この問題への私はコメントを得ました〜:
コード2
template < typename T>
class Y
{
public:
template <typename U = T, typename V= typename std::enable_if< std::is_same< int, typename U::TRAIT>::value, int >::type, typename X=int>
Y(X* = nullptr) { std::cout << "First" << std::endl; }
template <typename U = T, typename V= typename std::enable_if< !std::is_same< int, typename U::TRAIT>::value, float >::type>
Y() { std::cout << "Second" << std::endl; }
};
OK、それがコンパイルされます。しかし、縫い目を単純化しても問題はありません。
コード3
template < typename T>
class Y
{
public:
template <typename U = T, typename V= typename std::enable_if< std::is_same< int, typename U::TRAIT>::value, int >::type>
Y(int* = nullptr) { std::cout << "First" << std::endl; }
template <typename U = T, typename V= typename std::enable_if< !std::is_same< int, typename U::TRAIT>::value, float >::type>
Y() { std::cout << "Second" << std::endl; }
};
最後の例でも動作します! 1つのコンストラクタにデフォルトパラメータがありますが、このパラメータはテンプレート化されたものではありません。
私にとっては、ここで実行するルールを遅らせるためにどのルールが働いているのかはかなり不明です。
私の最初の誤解は、SFINAEがコンストラクタテンプレートをインスタンス化することによって行われ、1つのコンストラクタのみが利用可能になると考えたことです。これは真実ではありません!すべてのコンストラクタに設定された各パラメータは、異なる必要があります。どうして?さらに、テンプレート化されたパラメータでなければならない理由は?私の例3の縫い目は働くが、他の人は私にdummy and defaulted template parameter (like , typename Z = void)
を使うよう助言を与えた。誰かが私にこのトピックに関する少しの背景情報を与えることができますか?
http://stackoverflow.com/a/36500292/3953764 –
:
常にパラメータを追加するために回避する方法は、別の署名になり
ような何かをすることです* "私はSFINAEがコンストラクタテンプレートをインスタンス化し、コンストラクタが1つしか利用できないと考えましたが、これは真実ではありません!" *しかし、AAやBBの定義がなくてもエラーになります。したがって、この問題はテンプレートのインスタンス化には関係しません。すでに言われていることを言いましょう:単に 'void foo(bool b = false)'と 'void foo(bool b = true)'が異なるデフォルトを持っているため、定義に共存できないのと同じです。したがって、 ''と ''があります。 –
HostileFork