2014-10-23 13 views
7

Ho un std::map Sto provando a inizializzare con un elenco di inizializzazione. Lo faccio in due posti, in due modi diversi. Il primo funziona, mentre l'altro causa l'errore menzionato nel titolo."C2593: operator = is ambiguous" quando popolano std :: map

Ecco quello che funziona:

void foo() { 
    static std::map<std::string, std::string> fooMap = 
    { 
     { "First", "ABC" }, 
     { "Second", "DEF" } 
    }; 
} 

Anche se questo non lo fa:

class Bar { 
    public: 
     Bar(); 
    private: 
     std::map<std::string, std::string> barMap; 
}; 

Bar::Bar() { 
    barMap = { // <-- this is the error line 
     { "First", "ABC" }, 
     { "Second", "DEF" } 
    }; 
} 

Perché ottengo l'errore quando si cerca di inizializzare il membro della classe, mentre la cartina opere statiche? Al momento, posso compilare il membro creando innanzitutto una variabile locale e quindi scambiandolo con l'elemento simili:

Bar::Bar() { 
    std::map<std::string, std::string> tmpMap = { 
     { "First", "ABC" }, 
     { "Second", "DEF" } 
    }; 

    barMap.swap(tmpMap); 
} 

Tuttavia, questo si sente piuttosto intuitivo rispetto ad appena popolamento direttamente l'organo.


EDIT: Here's the compiler output.

+0

Questo compila su ideone: http://ideone.com/OkXujD – TNA

+2

@manabreak Sembra che sia un bug del compilatore. Si prega di mostrare il messaggio di errore completo. –

+0

Funziona su GCC 4.7.2. Che compilatore stai usando? –

risposta

11

Si tratta di un bug nel meccanismo di compilatori risoluzione di sovraccarico - o alla sua applicazione libreria standard. risoluzione sovraccarico chiaramente in [over.ics.rank]/3 che

- sequenza di elenco di inizializzazione L1 è in una sequenza di conversione di sequenza elenco inizializzazione L2 se L1 converte in std::initializer_list<X> per qualche X e L2 no.

Qui, X è std::pair<std::string, std::string>. L1 converte la vostra lista al parametro di

map& operator=(std::initializer_list<value_type> ilist); 

Mentre L2 converte l'elenco per uno dei parametri seguenti funzioni:

map& operator=(map&& other); 
map& operator=(const map& other); 

che chiaramente non sono initializer_list s.


Si potrebbe provare a utilizzare

barMap = decltype(barMap){ 
    { "First", "ABC" }, 
    { "Second", "DEF" } 
}; 

Che dovrebbe selezionare l'operatore di spostamento-assegnazione (Demo with VC++). Il provvisorio dovrebbe anche essere ottimizzato via secondo copia elision.

+1

Potresti dumbelo per me? Non riesco ancora a capire perché non funzioni nel tentativo di riassegnare. – manabreak

+0

@manabreak È ** un bug **. Leggi la mia prima frase. :) – Columbo

+1

@manabreak In realtà ho aggiunto una soluzione alternativa che funziona con i rextesters vC++. – Columbo

Problemi correlati