Pregunta

Estoy escribiendo una clase de plantilla y quiero permitir que existirá un método adicional solo para un determinado tipo de plantilla. Actualmente, el método existe para todos los tipos de plantillas, pero causa un error de compilación para todos los demás tipos.

Para complicar esto es que es un operador sobrecargado (). No estoy seguro si lo que quiero hacer es realmente posible aquí.

Esto es lo que tengo ahora:

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;
};

Quiero el T& versión siempre disponible, pero el T const& Versión solo disponible si Utility2<BASE> es válida. En este momento, ambos métodos existen, pero intentar usar la versión const proporciona un error de compilación extraño si Utility2<BASE> es inválido. Prefiero tener un error sensato, o incluso un error de "no hay función miembro".

es posible?

EDITAR: Después de leer los documentos de Boost, esto es lo que se me ocurrió, y parece funcionar:

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;
};

Por lo tanto, ese método no existe a menos que alguien intente usarlo con Utility2, y solo puede crear una utilidad2 si es válida para ese tipo de base. Pero cuando no es válido para ese tipo de base, MyClass no perderá el tiempo creando el método de accesorios.

¿Fue útil?

Solución

Sí, esto es posible, pero no con el parámetro de plantilla de clase directamente. boost::enable_if solo se puede usar con un parámetro de plantilla en el método en sí. Entonces, con un pequeño uso de 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;
};

Esto funciona, porque Utility2 solo se puede crear a partir de cierto tipo de base. Entonces, si el tipo base es otra cosa, la versión const de operador () no existirá.

Entonces, es algo muy menor. No me gana mucho. Pero fue bueno hacerlo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top