Как взять класс, который использует пакет параметров и имя типа, в качестве входного параметра для функции (c ++) - PullRequest
1 голос
/ 04 ноября 2019

Я создал класс, который принимает переменную шаблона typename и parameter pack. На следующем шаге я хочу иметь возможность передать два объекта этого класса в мою функцию.

Моя главная проблема - правильно передать параметры шаблона и объекты, чтобы можно было использовать мою функцию. Реализация моего класса.

//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(){
    }
};

Функция, которая принимает объекты MatrixND:

template<auto posT1, auto posT2, typename A, typename B>
auto constexpr function(const MatrixND<A> tensor1, const MatrixND<B> tensor2){

    return 0;
}

Я попробовал следующее, но выдает сообщение об ошибке «нет соответствующего вызова функции»:

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);

Сообщение об ошибке:

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);

Ответы [ 2 ]

4 голосов
/ 04 ноября 2019

Вам необходимо добавить пакеты параметров к параметрам шаблона function. Использование

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;
}

Позволяет вам вызывать функцию наподобие

auto foo = function<1,1>(matrix1, matrix1);

Обратите внимание, что для этого, чтобы скомпилировать ваш код, вам нужно изменить

auto matrix1 = new MatrixND<double, upper, lower, lower>(arrayc);

to

auto matrix1 = MatrixND<double, upper, lower, lower>(arrayc);

, поскольку вы на самом деле не хотите указатель на MatrixND, а на фактический MatrixND объект.

2 голосов
/ 04 ноября 2019

Когда вы вызываете функцию как

function<1,1, decltype(matrix1), decltype(matrix1)>(matrix1, matrix1);

, вы говорите, что аргументы шаблона A и B равны decltype(matrix1), что означает, что они действительно MatrixND<double, upper, lower, lower>.

Это, в свою очередь, означает, что, например, аргумент tensor1 будет иметь тип const MatrixND<MatrixND<double, upper, lower, lower>>. Это не то, что вы передаете.

Возможное решение состоит в том, чтобы не использовать MatrixND<A>MatrixND<B>) в списке аргументов, а только

template<auto posT1, auto posT2, typename A, typename B>
auto constexpr function(const A tensor1, const B tensor2){

    return 0;
}

И вам, вероятно, следуетПередавайте ссылки вместо значений в качестве аргументов.


Если вы сделаете то же самое с функцией, вам также не понадобятся аргументы шаблона для типов A и B, поскольку этобыть выведенным компилятором:

function<1,1>(matrix1, matrix1);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...