候选模板被忽略:替换失败(clang 错误但不是 g++)

candidate template ignored: substitution failure(error with clang but not g++)

我有代入失败的问题,一些类似问题的回答对我没有帮助。

代码如下:

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

我这样调用这个模板函数:

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

使用 g++ 编译。

使用clang++(linux)编译(clang++ -std=c++11 xxx.cpp)时,出现如下编译错误:

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)

为什么?

这是 clang 中的一个错误;当在 class 模板中定义定义数组类型的别名模板时,它会出现异常。事实上它可以被利用到 crash the compiler:

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

由于在您的情况下 Reference::matrix_t 不依赖于 Reference 的模板参数,最简单的解决方法是将 matrix_t 的定义移动到命名空间范围:

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

事实上,您甚至不需要使用 impl::matrix_t 来解决错误:

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!

这是 now fixed(修复应该在 clang 发布版本 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.