Candidate pattern ignored: replacement failed (error with clang but not g ++)

I have a problem replacing a replacement, and the answers to some of these questions do not help me.

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

And I call this template function as follows:

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

Using g ++, it compiles.

When using clang ++ (linux) to compile ( clang++ -std=c++11 xxx.cpp ) this led to the following compilation error:

 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) 

Why?

+8
c ++ c ++ 11 templates g ++ clang
source share
1 answer

This is a bug in clang; this is incorrect when an alias template template that defines the type of an array is defined inside the class template. In fact, it can be used to crash the compiler :

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

Since in your case Reference::matrix_t is independent of the arguments of the Reference template, the easiest workaround would be to move the definition of matrix_t to the namespace area:

 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 fact, you don’t even need to use impl::matrix_t to work around the error:

 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! 

This is now fixed (the fix should be in clang version 3.8.0):

[AST] Perform additional canonicalization for DependentSizedArrayType

We processed DependentSizedArrayTypes with the same element type, but with different expression sizes as equivalently canonical. This would lead to fancy behavior during template creation.

This fixes PR24212.

+4
source share

All Articles