Questo è anche il caso di g++
4.8.4 con il seguente:
g++ -g -pedantic --std=c++11 -o test main.cpp
Le impostazioni VS2015 sono tutti inadempienti.
Il problema è che il compilatore tenta di convertire un valore temporaneo restituito da ConvertsToPtr()
a un oggetto shared_ptr
. Quando il compilatore viene utilizzato con la parola chiave explicit
, questa conversione non si verifica mai utilizzando il costruttore. Tuttavia, durante l'esame con gdb
sembra che invece sta usando la funzione di conversione shared_ptr<A> const &()
per abbinare il Tipo appropriato. Questa conversione restituisce quindi un valore const shared_ptr &
che non ha ambiguità quando si richiama l'operatore di assegnazione (anche questo corrisponde ai risultati di wojciech Frohmberg).
Tuttavia, se si omette explicit
, viene restituito un oggetto di shared_ptr
. questo può essere abbinato o alla versione rvalue dell'operatore di assegnazione o alla versione del lvalue.
Secondo N4296, Tabella 11, quindi abbiamo, dopo la costruzione con lo conversion constructor
, un oggetto rvalue of shared_ptr
. Tuttavia, la risoluzione di sovraccarico trova due corrispondenze, entrambe di livello inferiore a Exact Match
(la versione di rvalue è Identity matching
mentre l'altra è inferiore a Qualification matching
).
Ho controllato anche su VS2015
e come indicato nei commenti, funziona. Tuttavia, usando il comando di debug di , il valore viene assegnato per priorità al valore . omologo della versione di rifrazione del valore costante.
MODIFICA: Ho guardato un po 'più in profondità nello standard e aggiungere la modifica. il testo eliminato relativo ai risultati VS2015
era errato, perché non ho definito entrambi i compiti. Quando entrambi i compiti sono stati dichiarati, preferisce il valore.
Suppongo che il compilatore VS distingue lo Identity
dalla corrispondenza Qualification
nella classifica. Tuttavia, come ho concluso, è il compilatore VS che è bacato. i compilatori g++
obbediscono allo standard indicato. Tuttavia dal momento che GCC 5.0 funziona come Visual Studio, la possibilità di bug del compilatore è sottile, quindi sarei felice di vedere altri approfondimenti di esperti.
MODIFICA: in 13.3.3.2 uno degli interruttori pareggio, dopo la classifica migliore che ho scritto su di esso, è:
— S1 and S2 are reference bindings (8.5.3) and neither refers to an implicit object parameter of a non-static member function declared without a ref-qualifier, and S1 binds an rvalue reference to an rvalue and S2 binds an lvalue reference.
V'è un esempio attaccato mostrando che un dato rvalue (riferimento non rvalue) dovrebbe corrispondere a un const int &&
sopra const int &
. Pertanto, suppongo, è lecito ritenere che sia rilevante per il nostro caso, anche se abbiamo il tipo &&
e non il tipo const &&
. Immagino, dopo tutto, che GCC
4.7.4.8 sia bacato dopo tutto.
Accettato da GCC 5+, respinto da 4.9 e Clang. –
Per quanto riguarda il motivo per cui si verifica questo errore: I * think * le due possibilità sono il 'const shared_ptr &' costruttore dal risultato della funzione di conversione di 'ConvertsToPtr', e il' shared_ptr && 'costruttore da un' shared_ptr temporaneo 'che è costruito da' Args = {ConvertsToPtr} '. Ma non sono sicuro che quelli siano fatti per essere ugualmente buoni. –
@Alf meh. my_namespace :: shared_ptr e std :: shared_ptr sono nomi diversi. – AndyJost