2013-05-13 6 views
2

У меня есть класс, который принимает параметр шаблона bool. Класс будет иметь несколько методов, которые мне нужно специализировать на параметре шаблона класса bool. Есть ли способ сделать это, не специализируясь на самом классе?C++ class member function specialization on bool values ​​

Foo :: бар() ниже является примером того, что я имею в виду, он не работает, так как станд :: is_same работает с типами и не значениями

Благодарности.

template<bool Mode> 
class Foo 
{ 
public: 
template<bool M=Mode, typename std::enable_if<std::is_same<M,true>::value>::type * = 0> 
void bar() 
{ 
    std::cout << "true" << std::endl; 
} 

template<bool M=Mode, typename std::enable_if<std::is_same<M,false>::value>::type * = 0> 
void bar() 
{ 
    std::cout << "false" << std::endl; 
} 
+0

[ 'станд :: is_same'] (http://en.cppreference.com/w/cpp/types/is_same) сравнивает ** типы **. 'M' является константой,' true' и 'false' являются значениями, т. Е. Они не являются типами. – dyp

ответ

3

Вам не нужно использовать std::is_same. std::enable_if уже принимает булево значение:

template <bool Mode> 
class Foo 
{ 
    public: 
     template <bool M = Mode, typename std::enable_if<M>::type* = nullptr> 
     void bar() 
     { 
      std::cout << "true" << std::endl; 
     } 

     template <bool M = Mode, typename std::enable_if<!M>::type* = nullptr> 
     void bar() 
     { 
      std::cout << "false" << std::endl; 
     } 
}; 

Вот является demo.

2

Вы на правильном пути. Просто используйте параметр шаблона напрямую:

template<bool M=Mode, typename std::enable_if<M == true>::type * = 0> 
void bar()         //^^^^^^^^^^ 
{ 
    std::cout << "true" << std::endl; 
} 
8

Возможно, мне что-то не хватает, но почему бы не использовать обычную добрую старую специализацию?

template <bool M> 
struct base_template { 
    void bar(); 
}; 

template <> 
inline void base_template<true>::bar() { std::cout << "true\n"; } 
template <> 
inline void base_template<false>::bar() { std::cout << "false\n"; } 
+0

Да, я думаю, я мог бы. Я думал, что если я хочу специализироваться на классе, мне придется снова переопределить все методы в специализированном классе, я вижу, что это не так. Тем не менее, я думаю, что код enable_if выглядит более чистым и более понятным, поскольку объявление функции объявляет о намерении специализироваться. –

+0

@MK .: Не так ли? Вы создаете разные перегрузки, которые, хотя они могут волшебным образом исчезать через SFINAE, вы должны быть осторожны в условиях, которые вы используете (т. Е. Проверка SFINAE должна предоставлять непересекающиеся наборы аргументов или вы получаете ошибки двусмысленности). В то же время, поскольку они являются несвязанными базовыми шаблонами, ничто не связывает один интерфейс с другим, поэтому вы можете ошибочно принимать аргументы/возвращаемое значение в одном из определений ... это не * специализация *, а * перегрузка *. –