Reputation: 739
I created a class that takes a typename
template variable and a parameter pack
. In the next step i want to be able to pass two objects of that class to my function.
My main problem is, passing the template parameters and the objects correctly to be able to use my function. My class implementation.
//auto as template parameter is for non-type parameter(c++17)
template <auto value> constexpr auto DIM = value;
//constexpr on values in header files(c++17)
inline constexpr auto const DIM3 = DIM <3>;
inline constexpr auto const DIM2 = DIM <2>;
enum Index : int {lower = 0, upper = 1};
template<int base, int exponent>
int constexpr pow(){
if constexpr(exponent == 0){
return 1;
}else{
return base * pow<base, exponent-1>();
}
}
template<int Size, typename T>
struct Array{
T array[Size];
Array(const T * a){
for(int i = 0; i < Size; i++){
array[i] = a[i];
}
}
};
//auto as template parameter is for non-type parameters(c++17)
template<typename T = double, auto ...IndicesN>
class MatrixND{
private:
const Array<pow<DIM3, sizeof...(IndicesN)>(), T> matrix;
public:
MatrixND(const T * arr): matrix(arr){}
template<auto ...args>
auto constexpr getElement(){
}
};
The function that takes MatrixND objects:
template<auto posT1, auto posT2, typename A, typename B>
auto constexpr function(const MatrixND<A> tensor1, const MatrixND<B> tensor2){
return 0;
}
I tried the following, but it throws an error message "no matching function call":
const double arrayc[27] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27};
auto matrix1 = new MatrixND<double, upper, lower, lower>(arrayc);
function<1,1, decltype(matrix1), decltype(matrix1)>(matrix1, matrix1);
The error message:
error: no matching function for call to ‘function<1, 1, MatrixND<double, (Index)1, (Index)0, (Index)0>*, MatrixND<double, (Index)1, (Index)0, (Index)0>*>(MatrixND<double, (Index)1, (Index)0, (Index)0>*&, MatrixND<double, (Index)1, (Index)0, (Index)0>*&)’
contraction<1,1, decltype(matrix1), decltype(matrix1)>(matrix1, matrix1);
Upvotes: 1
Views: 63
Reputation: 180415
You need to add the parameter packs to the template parameters of function
. Using
template<auto posT1, auto posT2, typename A, typename B, auto ...AIndicesN, auto ...BIndicesN>
auto constexpr function(const MatrixND<A, AIndicesN...> tensor1, const MatrixND<B, BIndicesN...> tensor2){
return 0;
}
Allows you to call function like
auto foo = function<1,1>(matrix1, matrix1);
Do note that for this to compile with your code you need to change
auto matrix1 = new MatrixND<double, upper, lower, lower>(arrayc);
to
auto matrix1 = MatrixND<double, upper, lower, lower>(arrayc);
since you don't actually want a pointer to a MatrixND
but an actual MatrixND
object.
Upvotes: 4
Reputation: 409136
When you call the function as
function<1,1, decltype(matrix1), decltype(matrix1)>(matrix1, matrix1);
you say that the template arguments A
and B
are decltype(matrix1)
, meaning they are really MatrixND<double, upper, lower, lower>
.
That in turn means that e.g. the argument tensor1
will have the type const MatrixND<MatrixND<double, upper, lower, lower>>
. Which is not what you pass.
A possible solution would be to not use MatrixND<A>
(and MatrixND<B>
) in the argument list, but only
template<auto posT1, auto posT2, typename A, typename B>
auto constexpr function(const A tensor1, const B tensor2){
return 0;
}
And you should probably pass references instead of values as arguments as well.
If you do like above with the function you also don't need the template arguments for the types of A
and B
as that would be deduced by the compiler:
function<1,1>(matrix1, matrix1);
Upvotes: 2