2011-02-02 2 views
7

Я пишу класс шаблона, и я хочу, чтобы дополнительный метод существовал только для определенного типа шаблона. В настоящее время метод существует для всех типов шаблонов, но вызывает ошибку компиляции для всех других типов.Могу ли я использовать boost :: enable_if для функции-члена?

Усложнение заключается в том, что это перегруженный оператор(). Не уверен, что то, что я хочу сделать, на самом деле возможно здесь.

Вот что я сейчас:

template<typename T, typename BASE> 
class MyClass : public BASE 
{ 
public: 

    typename T& operator() (const Utility1<BASE>& foo); 
    typename T const& operator() (const Utility2<BASE>& foo) const; 
}; 

Я хочу, чтобы версия T& всегда доступны, но версия T const& доступна только, если Utility2<BASE> действует. В настоящее время оба метода существуют, но попытка использовать версию const дает странную ошибку компиляции, если Utility2<BASE> недействителен. Я предпочел бы разумную ошибку или даже ошибку «нет такой функции-члена».

Возможно ли это?

EDIT: После прочтения подпиточного документы, вот что я придумал, и это похоже на работу:

template<typename T, typename BASE> 
class MyClass : public BASE 
{ 
public: 

    typename T& operator() (const Utility1<BASE>& foo); 

    template<typename U> 
    typename boost::enable_if<boost::is_same<Utility2<BASE>, U>, T>::type const & 
    operator() (const U& foo) const; 
}; 

Так что метод не существует, если кто-то пытается использовать его с Utility2, и они могут создавать только Utility2, если они действительны для этого типа BASE. Но когда это недействительно для этого типа BASE, MyClass не будет тратить время на создание метода доступа.

+0

Что вы подразумеваете под 'Utility2 ' is "valid"? – Nim

+0

Utility2 пытается вызвать метод на BASE. Только один тип BASE имеет этот метод. – Tim

+0

http://stackoverflow.com/questions/2937425/boostenable-if-class-template-method – Anycorn

ответ

4

Да, это возможно, но не с параметром шаблона класса напрямую. boost::enable_if может использоваться только с параметром шаблона самого метода. Таким образом, с небольшим использованием ЬурейеГо:

template<typename T, typename BASE> 
class MyClass : public BASE 
{ 
public: 
    typedef Utility2<BASE> util; 

    typename T& operator() (const Utility1<BASE>& foo); 

    template<typename U> 
    typename boost::enable_if<boost::is_same<util, U>, T>::type const & 
    operator() (const U& foo) const; 
}; 

Это работает, потому что Utility2 может быть создан только из определенного типа базы. Поэтому, если тип BASE - это что-то другое, версия const operator() не будет существовать.

Итак, это очень незначительная вещь. Это меня не очень устраивает. Но это было аккуратно.

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