Варианты реализации Variadi c - PullRequest
0 голосов
/ 31 марта 2020

Я пытался использовать Variadi c Tuples на Generi c Шаблоны и структуры. Идея состоит в том, чтобы получить максимум и сумму кортежа variadi c. До сих пор мне удавалось получить требуемые результаты, но мне пришлось использовать переменные Global stati c. Я разместил код ниже реализации.

    #include <iomanip>
    #include <complex>
    #include <cmath>
    #include <tuple>
    #include <string>
    #include <iostream>

    using namespace std;
    using namespace std::complex_literals;

    template<typename T>
    static T max;

    template<typename T>
    static T sum;

    template<typename T>
    static T average;

    template <typename T, typename Tuple, std::size_t N>
    struct Calculator
    {
    static void maximum(const Tuple& pack)
    {
    Calculator<T, Tuple, N - 1>::maximum(pack);
    T packValue = get<N - 1>(pack);
    if (packValue > max<T>)
    {
    //T max = get<0>(pack);
    //Try the above instead of the below code to calculate max
    max<T> = get<N - 1>(pack);
    }
    }

    static void summation(const Tuple& pack)
    {
    Calculator<T, Tuple, N - 1>::summation(pack);
    T packValue = get<N - 1>(pack);
    sum<T> += packValue;
    }

    static void averager(const Tuple& pack)
    {
    average<T> = sum<T> / N;
    }


    };

    template<typename T, typename Tuple>
    struct Calculator<T, Tuple, 1>
    {
    static void maximum(const Tuple& pack)
    {
    //T max = get<0>(pack);
    //Try the above instead of the below code to calculate max
    max<T> = get<0>(pack);
    }

    static void summation(const Tuple& pack)
    {
    sum<T> = get<0>(pack);
    }
    };




    int main()
    {
    tuple<double, double, double, double, double, double, double> t1 = make_tuple(16565.256, 45.539,     0.25, 1000.25, 1.25036, 35.66, 210.20);

    Calculator<double, tuple<double, double, double, double, double, double, double>, 7>::maximum(t1);

    cout << "Maximum is: " << max<double> << endl;

    Calculator<double, tuple<double, double, double, double, double, double, double>, 7>::summation(t1);
    cout << "Total Sum is: " << sum<double> << endl;

    Calculator<double, tuple<double, double, double, double, double, double, double>, 7>::averager(t1);
    cout << "Average is: " << average<double> << endl;



    std::complex<int> c2(22, 3);
    std::complex<int> ci(15, 41);
    tuple<std::complex<int>, std::complex<int> > ct1 = make_tuple(ci, c2);

    Calculator< std::complex<int>, tuple<std::complex<int>, std::complex<int> >, 2>::summation(ct1);

    cout << "Summation of complex numbers is: " << sum<std::complex<int>> << endl;

    }

Мой вопрос, возможно ли реализовать версию, которая не использует глобальные переменные stati c для хранения значений sum и max, но альтернативная реализация с использованием Variadi c Шаблоны и структуры, если это возможно?

1 Ответ

1 голос
/ 31 марта 2020

Вы используете шаблон переменной , поэтому у вас есть как минимум C ++ 14. В C ++ 14 вы можете использовать index_sequence как простой способ извлечь все элементы кортежа и переписать ваши рекурсивные функции, чтобы они не были рекурсивными:

template <typename T, typename Tuple, std::size_t N>
struct Calculator
{
template<size_t ... Indices>
static T maxHelper(const Tuple& pack, std::index_sequence<Indices...>)  {
    return std::max( {std::get<Indices>(pack)...} );
} // [1]

static T maximum(const Tuple& pack)  {
    return maxHelper(pack, std::make_index_sequence<N>{}); 
}

template<size_t ... Indices>
static T sumHelper(const Tuple& t, std::index_sequence<Indices...>)  {
    T arr[] = { std::get<Indices>(t)... }; // [2]
    return std::accumulate(arr,arr+N,T{}); // [3]
}

static T summation(const Tuple& pack) {
    return sumHelper(pack,std::make_index_sequence<N>{});
}
};

в [1] элементы кортежа извлечены в std::initializer_list, затем вызывается перегрузка std::max, принимающая этот список.

в [2] и [3] элементы кортежа извлекаются в массив, а суммирование выполняется std::accumulate.

Демо


Начиная с C ++ 17 используйте std::applyсложите выражение для суммирования):

template<class ... Args>
auto maxValue(std::tuple<Args...> t) {
    return std::apply( [](auto&&... args) { return std::max({args...}); },t);
}

template<class ... Args>
auto sumValue(std::tuple<Args...> t) {
    return std::apply( [](auto&&... args){ return (args + ...);} , t);
}

Демо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...