La specializzazione esplicita dopo l’istanza

Ho il seguente codice:

typedef vector<int> Vec;
typedef vector<Vec> VecOfVec;

template<typename Vec>
Vec DoSomething(const Vec &v);

template<>
VecOfVec DoSomething<VecOfVec>(const VecOfVec &v)
{
    VecOfVec r;
    for(auto i = v.begin(); i != v.end(); i++)
        r.push_back(DoSomething(*i));
    return r;
}

template<>
Vec DoSomething<Vec>(const Vec &v) //Error here
{
    return v; //for the sake of the example
}

Ottengo il seguente errore:

explicit specialization of 'DoSomething<vector<int> >' after instantiation

alla linea marcata.
Il compilatore insiste sul fatto che è già creata un’istanza DoSomething<vector<int> >, mentre non può, e un semplice programma in grado di provarlo:

typedef vector<int> Vec;
typedef vector<Vec> VecOfVec;

template<typename Vec>
Vec DoSomething(const Vec &v);

template<>
VecOfVec DoSomething<VecOfVec>(const VecOfVec &v)
{
    VecOfVec r;
    for(auto i = v.begin(); i != v.end(); i++)
        r.push_back(DoSomething(*i));
    return r;
}

Risultati in esterni non risolti.
Perché il compilatore dicendo che già istanziato quando è possibile e anche non? e perché non il compilatore trattare come simboli non risolti, mentre il linker fa?
So di commutazione il metodo di ordine risolve, ma voglio sapere perché è il compilatore a farlo.

InformationsquelleAutor Dani | 2011-10-14

 

2 Replies
  1. 11

    Il codice richiesto un implicito creazione di un’istanza presso DoSomething(*i). Il fatto che tu non definire il modello in che unità di traduzione significa che è impossibile creare un’istanza di una specializzazione, quindi DoSomething(*i) produce un “simbolo non risolto” (linker-) errore nel tuo caso. Per sbarazzarsi di errore, è necessario definire il modello che TU, o fornire una esplicita istanza direttiva di tale modello in una TU, in cui è possibile definire il modello.

    Il semplice fatto che il codice richiesto un implicito creazione di istanze per la specializzazione DoSomething<vector<int> > prima è esplicitamente previsto che la specializzazione è sufficiente per il programma malformati (senza diagnostica essere necessario, tuttavia, il compilatore fa un buon lavoro qui, che non è tenuto a fare).

    Come @CharlesBailey utilmente note, dichiarando la specializzazione esplicita è perfettamente sufficiente; una definizione può essere dato altrove, anche al di fuori dell’usando TU.

    • “senza una diagnostica essere necessario”: è diagnostico richiesto lo standard?
    • Penso che la parte “il semplice fatto che Il codice richiesto un implicito creazione di istanze per la specializzazione DoSomething<vector<int> > prima è esplicitamente previsto che la specializzazione è sufficiente per il programma di ammalarsi-formata” non è corretto o c’è qualcosa di mancante. Essa, invece, dovrebbe essere : il semplice fatto che Il codice richiesto un implicito creazione di istanze per la specializzazione DoSomething<vector<int> > da un full-specializzazione prima è esplicitamente previsto che la specializzazione è sufficiente per il programma di ammalarsi-formato. Mi corregga, se sbaglio. 🙂
    • in modo che entrambi dicono che è implicito diverso da esplicita a un livello non possono essere scambiati?
    • non importa se la richiesta viene da una specializzazione o un non-funzione di modello. Se hai scritto void foo() { DoSomething<vector<int> >(vector<int>()); } in luogo della sua funzione che contiene un loop, che sarebbe mal formato allo stesso modo.
    • Hai solo bisogno di dichiara una specializzazione esplicita prima che il codice che possa causare un implicito creazione di istanze di specializzazione. La definizione può essere altrove.
    • Quello che hai scritto non è implicita creazione di un’istanza. Comunque, quello che volevo dire è che se il implicita istanziazione avviene da una funzione di modello, quindi non sarebbe un errore, qualcosa di simile a questo : ideone.com/CJKzI
    • grazie, è stata aggiunta una nota.
    • Quello che ho scritto sono le cause di un implicito creazione di un’istanza. Si ottiene un mal formato di mancato recapito (NDR) programma anche quando si causa un implicito creazione di istanze all’interno di una funzione template: template<typename T> void f() { DoSomething<vector<int> >(vector<int>()); } prima di fornire la specializzazione esplicita.
    • Che è fonte di confusione per me. Se è implicita istanza, allora che cosa è che nel mio codice? ideone.com/CJKzI
    • causerebbe un implicito creazione di istanze di DoSomething<vector<int>> alla riga 27 nel tuo esempio se non mi hanno fornito la specializzazione esplicita. La chiamata in il modello di funzione è dipendente, non so ancora cosa specializzazione per la chiamata nel modello.
    • In un altro esempio lo stesso errore viene visualizzato utilizzando (Apple) Fragore, mentre g++ 5.3.0 è bene che. La menzionata dichiarazione di specializzazione esplicita risolve il problema. Qualcuno sa se il g++ è più indulgente in quel caso?

  2. 3

    In genere significa solo che non ha fornito un “prototipo” per il modello di specializzazione. In altre parole non dare il compilatore di un testa a testa che “ehi, ci sta per essere una specializzazione specifiche per questo tipo di funzione, in modo da non inserire in uno sbagliato.”

    Nel mio caso ho avuto un modello di specializzazione in .cpp file, ed ho ottenuto questo errore. Fornire un “prototipo di funzione” (che è il modello di specializzazione intestazione seguita da un punto e virgola, proprio come un normale prototipo di funzione) ha risolto il problema.

Lascia un commento