Могу ли я использовать boost :: enable_if для функции-члена? - PullRequest
7 голосов
/ 03 февраля 2011

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

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

Вот что я имею сейчас:

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> недопустимо.Я предпочел бы иметь явную ошибку или даже ошибку «нет такой функции-члена».

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

РЕДАКТИРОВАТЬ : после прочтения документов наддувавот что я придумал, и, похоже, он работает:

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 не будет тратить время на создание метода доступа.

1 Ответ

4 голосов
/ 24 февраля 2011

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

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.Так что, если BASE-тип является чем-то другим, константная версия operator () не будет существовать.

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

...