Domanda

C'è qualche possibilità di utilizzare enable_if con un operatore di tipo di conversione? Sembra difficile, dal momento che sia il tipo di ritorno e parametri lista sono impliciti.

È stato utile?

Soluzione

documentazione :
Non ci sembra essere un modo per specificare un volano per un operatore di conversione. Conversione costruttori, tuttavia, può avere abilitatori come argomenti extra di default.

Altri suggerimenti

Dalla piccola ricerca che ho fatto (e ignorando il C ++ 0x commento da Johannes), la mia risposta è che dipende da cosa si desidera che il enable_if per. Se si desidera che l'operazione di conversione per T di esistere o no dal tipo T allora sembra che la risposta è no, non c'è alcun modo in C ++ 03 (come diceva Ugo). Ma se avete bisogno il enable_if per cambiare il comportamento dell'operatore a seconda del tipo di T allora sì, c'è una soluzione che è quello di chiamare un abilitato helper funzione (chiamata to<T> come suggerito Matthieu).

#include<iostream>
#include<boost/utility/enable_if.hpp>
#include<boost/type_traits/is_class.hpp>

struct B{
    B(const B& other){}
    B(){}
};

struct A{
    template<class T>
    T to(typename boost::enable_if_c<not boost::is_class<T>::value, void*>::type = 0){
        std::clog << "converted to non class" << std::endl;
        return T(0);
    }
    template<class T>
    T to(typename boost::enable_if_c<boost::is_class<T>::value, void*>::type = 0){
        std::clog << "conveted to class" << std::endl;
        return T();
    }
    template<class T>
    operator T(){
        return to<T>();
    }
};

int main(){
    A a;
    double d = (double)a; // output: "converted to non class"
    B b = (B)(a); // output: "converted to class"
    return 0;
}

Per la cronaca, ero frustrato con questo per diversi giorni, fino a quando ho capito che volevo enable_if non per SFINAE ma per il cambiamento del comportamento in fase di compilazione. Si può anche trovare che questo è il vero motivo per il vostro bisogno di enable_if anche. Solo un suggerimento.

(Si prega di notare che questa è una risposta per il C ++ 98 epoca)

Anche se posso capire l'interesse theoritecal nella domanda, io personalmente astenersi dal usando operatori di conversione, per quanto possibile.

L'unico che io abbia mai usare con consistenza è la conversione di una pseudo-booleana (utilizzando il linguaggio sicuro Bool), per smart-puntatori o proxy, e come notato io uso un trucco per effettivamente impedire la piena semantica booleana .. .

Se mai voglia di facilitare la conversione, preferisco di gran lunga qualcosa lungo la linea di:

template <class T>
T to() const;

, che non soffre delle limitazioni (in termini di firma) dell'operatore di conversione e richiede l'invocazione esplicita, solo perché è un po 'più chiaro.

In realtà, ho trovato un modo; usiamo una classe privata, non utilizzato per contrassegnare una conversione che non dovrebbe esistere, e usiamo boost::mpl::if_ scegliere se produrre una conversione a NoConversion, o al tipo desiderato.

class A {
    class NoConversion { };
    template<class B> operator typename boost::mpl::if_<Cond, B, NoConversion>::type() const;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top