2014-11-15 4 views
7

Я пытаюсь переключиться между явным и неявным конструктором преобразования через enable_if.SFINAE enable_if Явный конструктор

Мой код в настоящее время выглядит

#include <type_traits> 
#include <cstdint> 

enum class enabled {}; 

template <bool B, typename T = void> using enable_if_t = typename std::enable_if<B, T>::type; 
template <bool B, typename T = void> using disable_if_t = typename std::enable_if<!B, T>::type; 

template <std::intmax_t A> struct SStruct 
{ 
    static constexpr std::intmax_t a = A; 
}; 

template <typename T> struct SCheckEnable : std::integral_constant<bool, T::a == 0> 
{ 
}; 

template <typename U, typename T> class CClass 
{ 
    public: 
     template <typename T2, enable_if_t<SCheckEnable<U>::value, enabled>...> constexpr CClass(T2 v) : val(v) {}; 
     template <typename T2, disable_if_t<SCheckEnable<U>::value, enabled>...> explicit constexpr CClass(T2 v) : val(v) {}; 

    private: 
     T val; 
}; 

int main() 
{ 
    CClass<SStruct<0>, double> a = 1;        // should use implicit constructor 
    CClass<SStruct<1>, double> b = CClass<SStruct<1>, double>(1); // should use explicit constructor 
} 

true в enable_if с зависит от параметра шаблона U

Если я пытаюсь собрать этот минимальный пример с g++ 4.9.1 и --std=c++11 включен я получаю следующее ошибки

sfinae.cpp: In substitution of ‘template<bool B, class T> using disable_if_t = typename std::enable_if<(! B), T>::type [with bool B = true; T = enabled]’: 
sfinae.cpp:13:52: required from here 
sfinae.cpp:7:95: error: no type named ‘type’ in ‘struct std::enable_if<false, enabled>’ 
template <bool B, typename T = void> using disable_if_t = typename std::enable_if<!B, T>::type; 
                          ^
sfinae.cpp:19:68: error: prototype for ‘constexpr CClass<U, T>::CClass(T2)’ does not match any in class ‘CClass<U, T>’ 
template <typename U, typename T> template <typename T2> constexpr CClass<U, T>::CClass(T2 v) : val(v) 
                    ^
sfinae.cpp:13:77: error: candidates are: template<class U, class T> template<class T2, int ...<anonymous> > constexpr CClass<U, T>::CClass(T2) 
    template <typename T2, disable_if_t<true, enabled>...> explicit constexpr CClass(T2 v); 
                      ^
sfinae.cpp:12:67: error:     template<class U, class T> template<class T2, enabled ...<anonymous> > constexpr CClass<U, T>::CClass(T2) 
    template <typename T2, enable_if_t<true, enabled>...> constexpr CClass(T2 v); 
                   ^

Любая идея как выбрать между явным и неявным построением на основе параметра U здесь?

+0

Я могу получить [это нормально работать] (http://coliru.stacked-crooked.com/a/f37eef8d7c290602). Не знаете, какие различия между вашим кодом и моим. – Rapptz

+0

Может ли 'constexpr' быть причиной этого? – Uroc327

+0

Нет. Это не должно оказывать никакого влияния на SFINAE. Возможно, это связано с определением его вне класса и тем, как вы это делаете, но я не совсем уверен. – Rapptz

ответ

3

Использование

template <class...> struct null_v : std::integral_constant<int, 0> {}; 

и определяют конструкторы как

template <typename T2, 
      long = null_v<enable_if_t<SCheckEnable<U>::value, T2>>::value> 
constexpr CClass(T2 v) : val(v) {}; 

template <typename T2, 
      int = null_v<disable_if_t<SCheckEnable<U>::value, T2>>::value> 
explicit constexpr CClass(T2 v) : val(v) {}; 

Making аргумент зависит и фактически экземпляр. Demo.

[temp.deduct]/8:

Если подмен приводит к недопустимому типа или выражения, типа вычета терпит неудачу. Недопустимым типом или выражением является тот, который был бы плохо сформированным, если он написан с использованием замещенных аргументов.

В вашем случае ошибка возникает за пределами любой замены, поэтому это не вызывает сбой дедукции, а скорее делает ваш код плохо сформированным.

+0

Скомпилирует и работает как следует ... Где именно лежит разница между моей попыткой и вашим решением? – Uroc327

+1

Если я правильно понял комментарий @ 0x499602D2, enable_if должен «обрабатывать» что-то с помощью 'T2', так как это параметр шаблона для включения или отключения конкретной функции. Правильно ли я понял? :) – Uroc327

+0

@ Uroc327 Отредактировал ответ. – Columbo

Смежные вопросы