【问题标题】:candidate template ignored: substitution failure(error with clang but not g++)候选模板被忽略:替换失败(clang 错误但 g++ 错误)
【发布时间】:2015-10-12 04:07:21
【问题描述】:

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

代码如下:

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)

为什么?

【问题讨论】:

  • oO 如果你删除了Referenceit compiles...的定义...
  • @Columbo 这正是问题所在。我需要在Partition类中使用Reference
  • @Columbo 将第一个别名模板更改为long[r][c]melpon.org/wandbox/permlink/0DHbcs3C0dm9H3gXò.Ó
  • @dyp 或者比较thisthis
  • @JorenHeit 是的,但这不是错误。我已经修复了namespace 错误,但错误仍然存​​在。所以我已经提取了上面的问题。

标签: c++ templates c++11 g++ clang


【解决方案1】:

这是clang中的一个错误;当定义数组类型的别名模板在类模板中定义时,它会出现异常。事实上它可以被利用到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] 为 DependentSizedArrayType 执行额外的规范化

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

这修复了 PR24212。

【讨论】:

  • 是的...只需添加不相关的namespace magic 即可解决该错误...对不起,我的英语不太好,但是“看,妈妈,没有手”是什么意思?
  • @Shindou 我非常疯狂的猜测是,clang 最终会得到一个对别名模板的悬空引用,并添加 namespace magic 确保悬空引用指向某个东西。 “看,妈妈,没有手”是个笑话——这是你骑自行车时把手从车把上拿开时说的。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-11-19
  • 1970-01-01
  • 2020-06-17
  • 1970-01-01
  • 1970-01-01
  • 2013-05-04
相关资源
最近更新 更多