2015-07-22 11 views
8

Ho un problema di errore di sostituzione e le risposte di alcune domande simili non mi aiutano.modello candidato ignorato: errore di sostituzione (errore con clang ma non g ++)

Ecco il codice:

template<int dim, int loop> 
class Reference{ 
public: 
    //... 
    template<int r, int c> using matrix_t = int[r][c]; 
    Reference(const matrix_t<dim, loop> &mat){} 
}; 

template<int dim, int loop> 
class Partition{ 
    // ... 
public: 
    // ... 
    template<int r, int c> using matrix = int[r][c]; 
    template<int r, int c> void readPattern(const matrix<r,c> &pattern) 
    { 
     // ... 
    } 
    // ... 
}; 

e chiamo questa funzione template in questo modo:

int main() 
{ 
    // ... 
    const int DENOISE_UR[3][4] = {/*...*/}; 
    Partition<1,2> partition; 
    partition.readPattern(DENOISE_UR); 
    // ... 
} 

Utilizzando g ++, si compila.

Quando si utilizza clang ++ (linux) per compilare (clang++ -std=c++11 xxx.cpp), è risultato il seguente errore di compilazione:

error: no matching function for call to 'readPattern' 
    note: candidate template ignored: substitution failure[ with r = 3, c = 4 ] 
     template<int r, int c> void readPattern(const matrix<r,c> &pattern) 

Perché?

+1

oO se si rimuove la definizione di 'Reference', [compila] (http: // melpon.org/wandbox/permlink/xx2K1gu0J4PFutiP) ... – Columbo

+0

@Columbo Questo è esattamente qual è il problema. Ho bisogno di usare la classe 'Reference' nella classe' Partition' – Shindou

+1

@Columbo Cambia il primo modello alias a 'long [r] [c]': http://melpon.org/wandbox/permlink/0DHbcs3C0dm9H3gX ò.Ó – dyp

risposta

4

È un bug in clang; si comporta in modo anomalo quando un modello di alias che definisce un tipo di matrice viene definito all'interno di un modello di classe. In realtà si può essere sfruttato per crash the compiler:

template<int I> 
struct S { 
    template<int J> using T = int[J]; 
    using U = T<I>; 
}; 
S<3>::U a; 

Dal momento che nel tuo caso Reference::matrix_t non dipende sugli argomenti template per Reference, la soluzione più semplice sarebbe quella di spostare la definizione di matrix_t in spazi dei nomi campo di applicazione:

namespace impl { template<int r, int c> using matrix_t = int[r][c]; } 
// ... 
template<int dim, int loop> 
class Reference { 
    //... 
    template<int r, int c> using matrix_t = impl::matrix_t<r, c>; 

In realtà, non è nemmeno bisogno di usoimpl::matrix_t per aggirare il bug:

namespace magic { template<int r, int c> using unused = int[r][c]; } // Huh? 
// ... 
template<int dim, int loop> 
class Reference { 
    //... 
    template<int r, int c> using matrix_t = int[r][c]; // Look ma, no hands! 

Questo è now fixed (la correzione deve essere in versione clang versione 3.8.0):

[AST] Perform additional canonicalization for DependentSizedArrayType

We treated DependentSizedArrayTypes with the same element type but differing size expressions as equivalently canonical. This would lead to bizarre behavior during template instantiation.

This fixes PR24212.

+0

Sì ... Aggiungendo semplicemente l'irrilevante 'spazio dei nomi magico' si aggirano i bug ... Mi dispiace non sto abbastanza bene con l'inglese, ma cosa fa 'Look ma, non significa "mani"? – Shindou

+0

@Shindou la mia ipotesi molto selvaggia sarebbe che quel clangore finisce con un riferimento ciondolante ad un modello di alias, e aggiungendo il 'namespace magic' si assicura che il riferimento ciondolante indichi qualcosa. "Look ma, no hands" è uno scherzo - è quello che dici quando vai in bicicletta e togli le mani dal manubrio. :) – ecatmur

Problemi correlati