候选模板忽略:替换失败(clang但不是g ++的错误) [英] candidate template ignored: substitution failure(error with clang but not 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屋!