nprogram’s blog

気ままに、プログラミングのトピックについて書いていきます

抽出・変換・統計をC++テンプレートメソッドで解く [C++]

はじめに

抽出・変換・統計をC++テンプレートメソッドで解きたいと思います。

  • std::accumulateとラムダ式
  • C++テンプレートメソッド
  • C++17畳み込み式、単項右畳み込みでコンパイル時に値を計算
#include <iostream>
#include <algorithm> //copy_if, for_each, transform
#include <vector>
#include <array>
#include <numeric> //iota, accumulate
#include <cassert>
using namespace std;


//C++テンプレートメソッドで解く
template <class T>
auto filter_map_fold(const T& nums)
{
    auto sum = 0;
    for (const auto num : nums) {
        sum += ((num%2==1)? num*2 : 0);
    }
    return sum;
}

//C++17畳み込み式、単項右畳み込みでコンパイル時に値を計算
template<typename... Args> 
constexpr auto filter_map_fold_constexpr(Args... args)
{
   return (((args%2==1)? args*2 : 0) + ...);
}

int main(void){
    // 指定された値から始まる整数列を生成する
    std::array<int, 10> nums;
    std::iota(nums.begin(), nums.end(), 1);
    
    constexpr auto ANSWER = 50;

    //std::accumulateで、答えを求める
    const auto result1 = std::accumulate(nums.cbegin(), nums.cend(), 0, 
        [](int acc, int n) { return (n%2==1)? acc+n*2 : acc; }
    );
    std::cout << "result1 : " << result1 << std::endl;
    assert(result1 == ANSWER);
    
    const auto result2 = filter_map_fold(nums);
    std::cout << "result2 : " << result2 << std::endl;
    assert(result2 == ANSWER);
    
    //C++17畳み込み式で、コンパイル時に答えを求める
    constexpr auto result3 = filter_map_fold_constexpr(1,2,3,4,5,6,7,8,9,10);
    std::cout << "result3 : " << result3 << std::endl;
    static_assert(result3 == ANSWER);
}