以元素方式添加两个范围的惯用且有效的方法

Mor*_*enn 6 c++ algorithm stl c++11

是否有任何有效和惯用的方式来执行以下操作?

std::vector<int> a = { 1, 2, 3, 4 };
std::vector<int> b = { 5, 6, 7, 8 };

for (std::size_t i = 0 ; i < a.size() ; ++i)
{
    a[i] += b[i];
}
Run Code Online (Sandbox Code Playgroud)

我试图避免括号/索引表示法,只使用迭代器,以便操作与任何具有前向迭代器的容器一起使用.我想到了以下解决方案:

std::vector<int> a = { 1, 2, 3, 4 };
std::vector<int> b = { 5, 6, 7, 8 };

std::transform(a.begin(), a.end(),
               b.begin(),
               a.begin(),
               std::plus<int>());
Run Code Online (Sandbox Code Playgroud)

然而,有冗余,a.begin()我只能使用+而不是+=.标准库中是否有一些算法允许我使用迭代器而没有任何冗余,或者我是否必须手动编写完整的循环?

Jer*_*fin 9

也许某些事情本来是习惯性的,但从来没有做过:

std::valarray<int> a = { 1, 2, 3, 4 };
std::valarray<int> b = { 5, 6, 7, 8 };
Run Code Online (Sandbox Code Playgroud)

现在你可以做到这些

std::valarray<int> c = a + b; //apply '+' element-wise; store result in c

a += b;  //apply '+=' element-wise 
Run Code Online (Sandbox Code Playgroud)

有关更多详细信息,请参阅std :: valarray文档.

  • 它是`std :: valarray`,不是吗?并且`a + = b`甚至更好,因为这是OP想要的. (3认同)

Mor*_*enn 1

我找不到我正在寻找的通用函数,最后使用了我命名的以下函数range_map(“将给定函数按元素映射到两个给定范围”)。正如评论所指出的,它实际上只不过是一个二进制文件std::for_each

template<class InputIt1, class InputIt2, class BinaryOperation>
void range_map(InputIt1 first1, InputIt1 last1,
               InputIt2 first2, BinaryOperation binary_op)
{
    while (first1 != last1) {
        binary_op(*first1++, *first2++);
    }
}
Run Code Online (Sandbox Code Playgroud)

plus_assign我通过以下方式创建了该类:

template<typename T>
struct plus_assign
{
    void operator()(T &lhs, const T &rhs) const 
    {
        lhs += rhs;
    }
};
Run Code Online (Sandbox Code Playgroud)

然后我的代码变成:

std::vector<int> a = { 1, 2, 3, 4 };
std::vector<int> b = { 5, 6, 7, 8 };

range_map(a.begin(), a.end(),
          b.begin(),
          plus_assign<int>());
Run Code Online (Sandbox Code Playgroud)

还有 function 的一元对应项range_map,用于将给定函子映射到范围:

template<class InputIt, class BinaryOperation>
void range_map(InputIt first, InputIt last,
               UnaryOperation unary_op)
{
    while (first != last) {
        unary_op(*first1++);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 考虑到所有其他答案,这确实是一个迫切需要的自我答案,并且值得投票。但请注意,您的一元“range_map”(顺便说一下,其参数应称为“unary_op”)只不过是“std::for_each”。 (2认同)