2015-07-22 5 views
8

Ich habe ein Problem der Substitution fehlgeschlagen, und Antworten auf einige ähnliche Fragen helfen mir nicht. HierKandidat Vorlage ignoriert: Substitution Fehler (Fehler mit Clang aber nicht g ++)

ist der Code:

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) 
    { 
     // ... 
    } 
    // ... 
}; 

Und ich nenne diese Template-Funktion wie folgt:

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

Mit g ++ kompiliert.

Wenn Klirren mit ++ (Linux) zu kompilieren (clang++ -std=c++11 xxx.cpp), führte es in den folgenden Zusammenstellung Fehler:

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) 

Warum?

+1

oO wenn Sie die Definition von 'Reference' entfernen, [es kompiliert] (http: // melpon.org/wandbox/permlink/xx2K1gu0J4PFutiP) ... – Columbo

+0

@Columbo Genau das ist das Problem. Ich brauche die Klasse 'Reference' in der Klasse' Partition' – Shindou

+1

@Columbo Ändern Sie die erste Aliasvorlage in 'long [r] [c]': http://melpon.org/wandbox/permlink/0DHbcs3C0dm9H3gX ò.Ó – dyp

Antwort

4

Es ist ein Bug in Clang; Es verhält sich falsch, wenn eine Alias-Vorlage, die einen Array-Typ definiert, in einer Klassenvorlage definiert ist. In der Tat kann es zu crash the compiler ausgenutzt werden:

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

Da in Ihrem Fall Reference::matrix_t auf der Vorlage Argumente Reference hängt nicht, wäre die einfachste Abhilfe die Definition von matrix_t zu bewegen seinem Anwendungsbereich auf Namensraum:

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 der Tat, Sie brauchen nicht einmal zu Verwendungimpl::matrix_t den Fehler zu umgehen:


Dies ist now fixed (das Update in Klirren Release-Version 3.8.0 sein sollte):

[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

Yeah ... Nur die irrelevante 'Namespace Magic' hinzufügen wird Workaround der Bug ... Es tut mir leid, ich bin nicht ganz gut mit Englisch, aber was" Look ma, keine Hände bedeuten? – Shindou

+0

@Shindou meine sehr wilde Vermutung wäre, dass Clam endet mit einem baumelnden Verweis auf eine Alias-Vorlage, und das Hinzufügen der "Namespace Magic" sorgt dafür, dass die dangling Referenz auf etwas zeigt. "Schau ma, keine Hände" ist ein Witz - das sagt man, wenn man Fahrrad fährt und die Hände vom Lenker nimmt. :) – ecatmur

Verwandte Themen