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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With