Я понятия не имею, какие правила следует использовать для использования SFINAE для перегрузки метода. Я запускаю несколько раз в проблемах, потому что там, где я знаю, есть больше правил. Поэтому я надеюсь, что существует ряд правил, которые можно кратко объяснить, чтобы помочь решить проблемы в целом, а не задавать вопросы снова и снова.Перегрузка SFINAE, правила которой должны быть рассмотрены
Моя точка старта здесь: 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
К этой проблеме я получил комментарий:
"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, изменяя свой код по:
Код 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; }
};
ОК, он компилирует. Но упрощение швов к работам также делает меня сомнительным.
Код 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; }
};
Последний пример также работает! Он имеет параметр по умолчанию в ONE из конструкторов, но этот параметр не является шаблоном.
Для меня сейчас совершенно неясно, какие правила работают, чтобы заставить вещи работать здесь.
Мое первое недоразумение в том, что я думал, что SFINAE имеет место путем создания экземпляра шаблона конструктора и становится доступным только один конструктор. Это не правда! Каждый набор параметров для всех конструкторов должен быть другим !? Зачем? И, кроме того, почему он должен или должен быть шаблонным параметром? Мой пример 3 швов для работы, но другие дали мне совет использовать dummy and defaulted template parameter (like , typename Z = void)
. Может ли кто-нибудь дать мне немного справочной информации по этой теме?
http://stackoverflow.com/a/36500292/3953764 –
* «Я думал, что SFINAE имеет место, создавая экземпляр шаблона конструктора, и доступен только один конструктор. Это не правда!» * => Но вы получаете ошибку даже без определения AA или BB. Таким образом, проблема не связана с созданием шаблона. Повторяя уже сказанное: это так же, как «void foo (bool b = false)» и «void foo (bool b = true)» не могут сосуществовать в определении только потому, что у них разные значения по умолчанию. Таким образом, это с ' и' '. –
HostileFork