变换和累加

Nor*_*löw 6 c++ algorithm stl transform accumulate

是否有人编写了一个符合C++ STL标准的算法,该算法结合std::transformstd::accumulate支持单通道算法,支持一元,二元和甚至(n-ary!)变体,比如说std::transformed_accumulate?我想要这个,因为我发现这种模式在例如线性代数中是高度可重用的,例如在(l1-)范数计算中.l1范数计算元素绝对值的总和.

Dav*_*eas 9

嗯......我敢打赌,你可以通过将转换嵌入二元谓词,转换元素并在转换后累积来实现.

struct times2accumulator {
   int operator()( int oldvalue, int newvalue ) const {
      return oldvalue + 2*newvalue;
   }
};
int r = std::accumulate( v.begin(), v.end(), 2, times2accumulator() );
Run Code Online (Sandbox Code Playgroud)

该仿函数相当于:

struct times2 {
   int operator()( int x ) {
      return 2*x;
   }
};
std::vector<int> tmp; tmp.reserve( v.size() );
std::transform( v.begin(), v.end(), std::back_inserter(tmp), times2 );
int r = std::accumulate( tmp.begin(), tmp.end(), 0 );
Run Code Online (Sandbox Code Playgroud)

当然,这可以是通用的,只需将转换仿函数传递给通用基础仿函数:

template <typename Transform>
struct transform_accumulator_t {
    Transform t;
    transform_accumulator_t( Transform t ) : t(t) {}
    int operator()( int oldvalue, int newvalue ) const {
        return oldvalue + t(newvalue);
    }
};
// syntactic sugar:
template <typename T>
transform_accumulator_t<T> transform_accumulator( T t ) {
    return transform_accumulator_t<T>(t);
}
int r = std::accumulate(v.begin(), v.end(), 0, transform_accumulator(times2));
Run Code Online (Sandbox Code Playgroud)

您还可以概括容器中的类型...甚至可以创建一个更通用的transform_accumulator,它同时接收累加器和转换函子并按顺序应用它们.实际实施留给读者练习.