是否有任何有效且惯用的方式来执行以下操作?
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];
}
我试图避免括号/索引表示法,只使用迭代器,以便操作与任何具有前向迭代器的容器一起使用。我想到了以下解决方案:
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>());
但是,a.begin()
存在冗余,我只能使用+
而不是+=
。标准库中是否有一些算法允许我使用迭代器而没有任何冗余,或者我是否必须手动编写完整的循环?
答案 0 :(得分:8)
也许某些事情本来是惯用的,但从来没有做过:
std::valarray<int> a = { 1, 2, 3, 4 };
std::valarray<int> b = { 5, 6, 7, 8 };
现在你可以做这些
std::valarray<int> c = a + b; //apply '+' element-wise; store result in c
a += b; //apply '+=' element-wise
有关详细信息,请参阅documentation of std::valarray。
答案 1 :(得分:4)
如果您不止一次使用它,并且您对标准库的精神中的简单界面感兴趣,您可以为特定用例创建一个简单的模板类(我将其称为“范围增量” “),写下类似的东西:
#include<vector>
#include<algorithm>
#include<iostream>
template<typename InputIt>
InputIt range_increment(InputIt dbeg, InputIt dend, InputIt sbeg) {
while(dbeg!=dend) {
*(dbeg++) += (*sbeg++);
}
return dbeg;
}
int main() {
std::vector<int> a = { 1, 2, 3, 4 };
std::vector<int> b = { 5, 6, 7, 8 };
range_increment(a.begin(), a.end(), b.begin());
for(auto x:a) {
std::cout<<x<<std::endl;
}
}
哪个收益率:
6
8
10
12
答案 2 :(得分:3)
a.begin()
的冗余有什么问题?
如果您对此不满意,请创建自己的算法:transform_inplace
template <class InputIterator, class OutputIterator, class BinaryOperator>
OutputIterator transform_inplace (InputIterator first,
InputIterator last,
OutputIterator result,
BinaryOperator op)
{
while (first != last) {
*result = op(*result, *first);
++result;
++first;
}
return result;
}
答案 3 :(得分:2)
不确定我称之为“惯用语”,但是:
assert(a.size()==b.size());
auto bi = b.begin();
for (auto& i : a) {
i += *(bi++);
}
非常简洁。
答案 4 :(得分: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++);
}
}
我通过以下方式创建了课程plus_assign
:
template<typename T>
struct plus_assign
{
void operator()(T &lhs, const T &rhs) const
{
lhs += rhs;
}
};
然后我的代码变成了:
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>());
还有函数range_map
的一元对应物,用于将给定的仿函数映射到范围:
template<class InputIt, class BinaryOperation>
void range_map(InputIt first, InputIt last,
UnaryOperation unary_op)
{
while (first != last) {
unary_op(*first1++);
}
}
答案 5 :(得分:0)
使用运算符重载
#include <vector>
std::vector<int>& operator += (std::vector<int>& a, std::vector<int> const& b)
{
for(size_t i = 0; i != a.size(); ++i)
a[i] += b[i];
return a;
}
int main(int argc, char * argv[])
{
std::vector<int> a { 1, 3, 5, 7, 9};
std::vector<int> b { 2, 4, 6, 8, 10};
a += b;
return 0;
}