candidate template ignored: substitution failure(e

2019-04-23 18:22发布

I have a problem of substitution failure, and answers of some similar 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 like so:

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), it resulted in the following compiling 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?

1条回答
该账号已被封号
2楼-- · 2019-04-23 19:01

It's a bug in clang; it misbehaves when an alias template defining an array type is defined within a class template. In fact it can be exploited 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 does not depend on the template arguments to Reference, the simplest workaround would be to move the definition of matrix_t to namespace scope:

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 workaround the 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!

This is now fixed (the fix should be in clang release version 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.

查看更多
登录 后发表回答