2011-02-02 13 views
7

Sto scrivendo una classe template e voglio consentire a un metodo aggiuntivo di esistere solo per un determinato tipo di template. Attualmente il metodo esiste per tutti i tipi di modello, ma causa un errore di compilazione per tutti gli altri tipi.Posso usare boost :: enable_if su una funzione membro?

Complicando questo è che si tratta di un operatore sovraccarico(). Non sono sicuro se ciò che voglio fare sia effettivamente possibile qui.

Ecco quello che ho adesso:

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 la versione T& sempre a disposizione, ma la versione T const& disponibile solo se Utility2<BASE> è valido. In questo momento, esistono entrambi i metodi, ma il tentativo di utilizzare la versione const fornisce un errore di compilazione strano se Utility2<BASE> non è valido. Preferirei avere un errore ragionevole, o anche un errore di "nessuna funzione membro".

È possibile?

EDIT: Dopo aver letto la documentazione spinta, ecco cosa mi è venuta in mente, 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 il metodo non esiste a meno che qualcuno cerca di usarlo con Utility2 e possono creare solo Utility2 se è valido per quel tipo BASE. Ma quando non è valido per quel tipo di BASE, MyClass non perderà tempo creando il metodo accessor.

+0

cosa intendete per 'Utilità2 ' è "valido"? – Nim

+0

L'utility2 tenta di chiamare un metodo su BASE. Solo un tipo di BASE ha effettivamente quel metodo. – Tim

+0

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

risposta

4

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

Questo funziona, perché Utility2 può essere creato solo da un certo tipo di base. Quindi se il tipo BASE è qualcos'altro, la versione const dell'operatore() non esiste.

Quindi, è una cosa molto secondaria. Non mi guadagna molto. Ma era pulito da fare.

Problemi correlati