2011-01-21 9 views
5

mio codice problema:C++ sovraccarico: stringa letterale vs boost :: funzione ambiguità

#include <string> 
#include <boost/function.hpp> 

void func (const std::string&) {} 
void func (const boost::function<void()>&) {} 

int main() { 
    func (main); // good 
    func ("bad"); 
    return 0; 
} 

=>

error: call of overloaded ‘func(const char [4])’ is ambiguous 
overload.cpp:4: note: candidates are: void func(const std::string&) 
overload.cpp:5: note:     void func(const boost::function<void()()>&) 

So che potrei risolvere questo chiamando esplicitamente func (string ("cattivo ")); o fornendo una funzione (const char *), ma mi chiedo se c'è un modo per mantenere il lato del chiamante come nell'esempio e senza introdurre più sovraccarichi.

Forse qualcosa con boost :: enable_if? Grazie per eventuali suggerimenti.

+0

pensate davvero che la causa sia il sovraccarico che richiede 'boost :: function', avete tentato ad esempio di compilare senza tale sovraccarico? Funzionerà? – Nim

+1

sì è causato dalla funzione boost ::. L'esempio che ho pubblicato riproduce l'intera situazione. – denis

+0

sì - non ho provato prima di chiedere, solo un po 'perplesso che questo era il caso - sembra che sia .. hmm .. a corto di fornire sovraccarichi per tutto, non sono sicuro che ci sia una soluzione pulita per questo ... – Nim

risposta

4

non si può facilmente risolvere questo problema. boost::function<> e std::function<> non supportano solo i functors richiamabili da f(), ma puntano anche ai membri richiamabili da (secondArg.*firstArg)() e membri di dati, quindi i loro costruttori fondamentalmente eseguono lo slurp di tutto e decidono in seguito cosa fare del tipo.

Non è affatto banale scrivere una classe di test SFINAE che protegge da conversioni implicite (e non sono nemmeno sicuro se sarebbe possibile, dal momento che la libreria Standard non lo fa. qualche ragione). Ricorda che un tipo può essere chiamabile a causa di molte proprietà differenti - potrebbe avere una funzione di conversione per funzionare con il tipo di puntatore ecc. Pp. Scrivere una classe SFINAE che potrebbe fare questo lavoro significa rifiutare una conversione implicita in alcuni casi e accettare una conversione implicita in altri casi basati su proprietà davvero non ovvie.

Se si desidera evitare questa ambiguità, proverei semplicemente a scegliere un nome di funzione diverso o se si tratta di un problema one-shot, eseguire il cast sul lato del chiamante.

+1

Vecchia domanda, ma per i futuri lettori è disponibile un rapporto sui difetti per 'std :: function'. Vedi [2132. std :: function ambiguity] (http://cplusplus.github.io/LWG/lwg-active.html#2132) attualmente implementato in g ++ 4.8. –

0

aggiungere questo:

void func (const char *s) { func(string(s)); } 

aggiornamento

template<class A0, ...> 
void func (const A0 &a0, ...) { 
    func(argize(a0), ...); // convert chars to strig, otherwise jut pass 
} 
+0

il problema è, il codice verrà effettivamente generato automaticamente e ci sono probabilmente già molti sovraccarichi come func (stringa); func (string, int); func (string, int, boost :: function) e così via. Quindi aggiungere char * -overloads non è purtroppo un'opzione. – denis

+0

@denis vedi aggiornamento – Anycorn

Problemi correlati