2015-02-15 15 views
6

Qualcuno potrebbe spiegare come risolvere l'ambiguo avviso di sovraccarico per make_unique, da dove viene l'errore e cosa significa esattamente (capisco cosa sia un sovraccarico ambiguo è ma non sono sicuro perché ne ottengo uno per questo particolare codice)? Sto usando C++ 11, quindi uso il modello raccomandato da Herb Sutter.C++ 11/14 make_unique sovraccarico ambiguo per std :: string

Utilizzando io ottenere il seguente errore:

Error 4 error C2668: 'make_unique' : ambiguous call to overloaded function 

E il mouse sopra tooltip in Visual Studio 13 mi dà il seguente ai metodi:

function template "std::enable_if<!std::is_array<_Ty>::value, std::unique_ptr<_Ty,std::default_delete<_Ty>>>::type std::make_unique<_Ty,_Types...>(_Types &&..._Args)" 
function template "std::unique_ptr<T, std::default_delete<T>> make_unique<T,Args...>(Args...) 
argument types are: std::string 

Il secondo dovrebbe essere quello chiamato dal modello make_unique

/* Will be part of c++14 and is just an oversight in c++11 
* From: http://herbsutter.com/gotw/_102/ 
*/ 
template<typename T, typename ...Args> 
std::unique_ptr<T> make_unique(Args&& ...args){ 
    return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); 
} 

Il costruttore da inoltrare a:

Shader(const std::string& name); 

Il codice che genera l'errore

std::string _name = "Shader"; 
std::unique_ptr<Shader> s = make_unique<Shader>(_name); 

risposta

3

La chiamata è ambigua perché si fare hanno std::make_unique, come dimostrano i contenuti tooltip lei cita. E anche se non hai scritto std::, dal momento che stai passando un std::stringargument-dependent lookup kicks in to search that namespace automatically.

Quando si dice "Sto usando C++ 11", non è giusto, perché Visual Studio non ti permette di scegliere quale standard scrivere. Ti fornisce solo l'ultimo supporto che ha radunato per qualsiasi caratteristica data. E, a quanto pare, Visual Studio 2013 ha C++ 14 std::make_unique.

Rimuovere il proprio.

+0

Buona cattura. Ma la domanda rimanente è perché VS vede entrambi come candidati. Probabilmente OP ha usato 'using namespace std;'? Quale è un'altra cosa che OP dovrebbe risolvere. –

+0

Questa è stata la mia prima ipotesi e ho scansionato tutti i file per l'utilizzo di namespace std; Purtroppo questo non è il problema :( Non c'è più alcun namespace per qualsiasi namespace, e non capisco perché VS veda il metodo C++ 14 :) Mi manca qualcosa o è possibile che usi la versione std anche se non si usa più lo spazio dei nomi? Sono abbastanza sicuro che la risposta sia corretta, ma aspetto l'approvazione finché qualcuno non trova o spiega perché viene utilizzato il metodo C++ 14. – NoxMortem

+1

Ok, la risposta è sicuramente corretta come: make_unique (_nome) lo risolve. Rimane ancora la piccola domanda in più per cui VS vede il metodo C++ 14 senza dare lo spazio dei nomi. Un'altra domanda, se uso semplicemente i metodi C++ 14, ci sono alcune cose di cui ho bisogno di essere a conoscenza oltre a quello che ovviamente ha bisogno di un compilatore capace di C++ 14 per costruire il progetto? – NoxMortem

-1

Sembrerebbe che non sia possibile farlo in Visual Studio.

È un bug.

La soluzione migliore è, come da questa domanda, How to Detect if I'm Compiling Code With Visual Studio 2008?, continuare a utilizzare vari #ifdefs per gestire casi in cui lo studio visivo è ancora troppo spazzatura per poter supportare le funzionalità di base.

Usa:

#if (_MSC_VER == 1500) 
    // ... Do VC9/Visual Studio 2008 specific stuff 
#elif (_MSC_VER == 1600) 
    // ... Do VC10/Visual Studio 2010 specific stuff 
#elif (_MSC_VER == 1700) 
    // ... Do VC11/Visual Studio 2012 specific stuff 
#endif 
+1

No, non è un bug, e ho mostrato come puoi farlo. Hai letto la mia risposta? Sei la persona che l'ha downvoted oggi? Perché? –

+0

@LightnessRacesinOrbit È un bug. make_unique si risolve senza usarlo su qualsiasi classe in std ::, ad es. make_unique () risolverà comunque l'uso di std :: make_unique. Come mai non è un bug? (Si noti in particolare che clang lo risolve correttamente: è solo uno studio visivo problematico) – Doug

+1

Se 'make_unique ()' ha un bug allora questo è qualche altro problema interamente_. Leggi di nuovo la domanda. Si tratta di 'make_unique (_nome)' dove '_name' è un' std :: string'. ADL si attiva. È un comportamento standard al 100%. La cosa a cui questa domanda si pone non è un bug. Se hai trovato un bug in qualche altro pezzo di codice, allora ottimo, ma questo non rende "è un bug" una risposta corretta a questa domanda. Non è! –

Problemi correlati