2015-07-22 14 views
8

Mam problem z brakiem wymiany, a odpowiedzi na niektóre podobne pytania nie pomagają mi.Szablon kandydata zignorowany: błąd zastąpienia (błąd z clang ale nie g ++)

Oto kod:

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

I wywołać tę funkcję szablonu tak:

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

Korzystanie g ++, kompiluje.

Przy użyciu szczęk ++ (Linux) do kompilacji (clang++ -std=c++11 xxx.cpp), wynikało to w następujący opracowującym błędu:

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) 

Dlaczego?

+1

oO jeśli usunąć definicję 'Reference' [kompiluje] (http: // melpon.org/wandbox/permlink/xx2K1gu0J4PFutiP) ... – Columbo

+0

@ Columbo To jest właśnie problem. Muszę użyć klasy 'Reference' w klasie' Partition' – Shindou

+1

@ Columbo Zmień pierwszy szablon aliasu na 'long [r] [c]': http://melpon.org/wandbox/permlink/0DHbcs3C0dm9H3gX ò.Ó – dyp

Odpowiedz

4

To błąd w klangu; źle działa, gdy szablon aliasu definiujący typ tablicy jest zdefiniowany w szablonie klasy. W rzeczywistości może być wykorzystana do crash the compiler:

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

Ponieważ w przypadku Reference::matrix_t nie zależy od argumentów szablonu do Reference, najprostszy Rozwiązaniem byłoby przenieść definicji matrix_t do przestrzeni nazw zakres:

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>; 

W rzeczywistości, nawet nie trzeba użytkuimpl::matrix_t aby obejść ten problem:

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! 

To now fixed (poprawka powinna być w Clang wydanie wersji 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

Tak ... Dodanie nieistotnej "magii nazw" spowoduje obejście błędu ... Przykro mi, nie jestem całkiem zadowolony z języka angielskiego, ale co to jest "Look ma, żadne ręce nie oznaczają? – Shindou

+0

@Shindou moje bardzo dzikie przypuszczenie byłoby, że klang kończy się zwisającym odwołaniem do szablonu aliasu, a dodanie "magii przestrzeni nazw" zapewnia, że ​​zwisające odniesienie wskazuje na coś. "Look ma, no hands" to żart - to jest to, co mówisz, kiedy jedziesz na rowerze i zdejmujesz ręce z kierownicy. :) – ecatmur