Domanda

Sto scrivendo una classe di modelli e voglio consentire a un metodo aggiuntivo di esistere solo per un certo tipo di modello. Attualmente il metodo esiste per tutti i tipi di modelli, ma provoca un errore di compilazione per tutti gli altri tipi.

Complicando questo è che è un operatore sovraccarico (). Non sono sicuro se quello che voglio fare sia effettivamente possibile qui.

Ecco quello che ho ora:

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

voglio il T& versione sempre disponibile, ma il T const& versione disponibile solo se Utility2<BASE> è valido. In questo momento, entrambi i metodi esistono, ma il tentativo di utilizzare la versione const fornisce uno strano errore di compilazione se Utility2<BASE> è invalido. Preferirei avere un errore sensato, o persino un errore "nessuna funzione di membro".

È possibile?

MODIFICARE: Dopo aver letto i documenti di boost, ecco cosa ho escogitato e sembra funzionare:

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

In modo che quel metodo non esista a meno che qualcuno non cerchi di usarlo con Utility2 e può creare un utilità2 solo se è valido per quel tipo di base. Ma quando non è valido per quel tipo di base, Myclass non perderà tempo a creare il metodo degli accessori.

È stato utile?

Soluzione

Sì, questo è possibile, ma non con il parametro del modello di classe direttamente. boost::enable_if può essere utilizzato solo con un parametro modello sul metodo stesso. Quindi, con un piccolo utilizzo di 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;
};

Funziona, perché Utility2 può essere creata solo da un determinato tipo di base. Quindi, se il tipo di base è qualcos'altro, la versione const dell'operatore () non esiste.

Quindi, è una cosa molto minore. Non mi guadagna molto. Ma era bello da fare.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top