候选模板忽略:替换失败(clang但不是g ++的错误) [英] candidate template ignored: substitution failure(error with clang but not g++)

查看:697
本文介绍了候选模板忽略:替换失败(clang但不是g ++的错误)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个替换失败的问题,一些类似问题的答案不能帮助我。



这里是代码:

 模板< int dim,int loop> 
class Reference {
public:
// ...
template< int r,int c>使用matrix_t = int [r] [c];
参考(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.readPattern(DENOISE_UR);
// ...
}

使用g ++编译。 / p>

当使用clang ++(linux)编译( clang ++ -std = c ++ 11 xxx.cpp )时,导致以下编译错误:

 错误:没有匹配的函数调用'readPattern'
注意:候选模板忽略:替换失败[with r = 3,c = 4]
template< int r,int c> void readPattern(const matrix< r,c& pattern)

为什么?

解决方案

这是clang中的错误;当在类模板内定义定义数组类型的别名模板时,会出现错误。实际上,它可以被利用来崩溃编译器

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

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

  namespace impl {template< int r,int c&使用matrix_t = int [r] [c]; } 
// ...
template< int dim,int loop>
class Reference {
// ...
template< int r,int c>使用matrix_t = impl :: matrix_t< r,c>

事实上,你甚至不需要 impl :: matrix_t 以解决该错误:

 命名空间magic {template< int r ,int c> using unused = int [r] [c]; } // Huh? 
// ...
模板< int dim,int loop>
class Reference {
// ...
template< int r,int c>使用matrix_t = int [r] [c]; //看ma,没有手!






这是现在已修复(修正应该在clang版本3.8.0中):


[AST]对DependentSizedArrayType执行额外的规范化



我们使用相同的元素类型处理DependentSizedArrayTypes, b $ b不同大小表达式作为等价规范。这将导致
在模板实例化期间出现奇怪的行为。



这修复了PR24212。



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?

解决方案

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.

这篇关于候选模板忽略:替换失败(clang但不是g ++的错误)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆