我正在尝试编写一个二进制函数,它接受两个向量(长度相同)并按值添加它们。由于某种原因,以下代码不起作用:
struct Plusval : binary_function <std::vector<int>,std::vector<int>,std::vector<int> >
{
std::vector<int> operator() (const std::vector<int>& x, const std::vector<int>& y) const
{
std::vector<int> ret(x);
std::vector<int>::iterator itx,ity;
ity=y.begin();
for (itx=ret.begin();itx<ret.end();++itx)
{
ret[*itx]+=y[*ity];
++ity;
}
return ret;
}
};
我收到错误,我不能做ity = y.begin() 但是,以下代码可以正常工作
struct Plusval : binary_function <std::vector<int>,std::vector<int>,std::vector<int> >
{
std::vector<int> operator() (const std::vector<int>& x, const std::vector<int>& y) const
{
std::vector<int> ret(x);
std::vector<int> yloc(y);
std::vector<int>::iterator itx,ity;
ity=yloc.begin();
for (itx=ret.begin();itx<ret.end();++itx)
{
ret[*itx]+=yloc[*ity];
++ity;
}
return ret;
}
};
显然,第二个版本需要更长的时间(因为它必须复制一个额外的向量)。是因为输入是一个常量向量吗?如果是,是否有任何理由需要?请注意,我打算使用此函数作为boost :: mpi中allreduce()函数的输入,如果这有任何区别
答案 0 :(得分:4)
您将ity
定义为vector::iterator
y
为const
并返回const_iterator
。
更重要的是:不要使用binary_function
。适配器已被弃用。
此外,您的功能不能满足您的需求。 * itx返回存储在itx
指向的位置的值,您可以使用它来索引您打算返回vector
。
我会用二进制transform
来写这个。
std::vector<int> res;
std::transform(begin(x), end(x), begin(y),
std::back_inserter(res), std::plus<int>());
答案 1 :(得分:1)
错误是您不能将非const迭代器与const容器一起使用,因为这会破坏const正确性。你应该在第二个参数上使用std::vector<int>::const_iterator
。
除此之外,第一个块中的实现不会按照您的声明执行。您正在迭代容器并使用存储的值索引到容器中并在那里进行更新。如果你真的想要从两个容器中添加值,那么它比这简单得多:
struct PlusVal
{
std::vector<int> operator()( std::vector<int> lhs, std::vector<int> const& rhs )
{
assert( lhs.size() == rhs.size() );
for (std::vector<int>::size_type i = 0; i < lhs.size; ++i )
lhs[i] += rhs[i];
return lhs;
}
};
如果你想用迭代器做到这一点,它同样很简单:
struct PlusVal
{
std::vector<int> operator()( std::vector<int> lhs, std::vector<int> const& rhs )
{
assert( lhs.size() == rhs.size() );
std::vector<int>::iterator it = lhs.begin(), end = lhs.end();
std::vector<int>::const_iterator rit = rhs.begin();
while ( it != end )
*it++ += *rit++;
return lhs;
}
};
答案 2 :(得分:0)
您正在寻找std::vector::const_iterator类型
std::vector<int> operator() (const std::vector<int>& x, const std::vector<int>& y)
{
std::vector<int> result;
// Not strictly necessary, but helps with performance a bit
result.reserve(std::min(x.length(), y.length());
for (std::vector<int>::const_iterator x_it = x.begin(),
y_it = y.begin();
x_it != x.end() && y_it != y.end();
++x_it, ++y_it)
{
result.push_back(*x_it + *y_it);
}
return result;
}
答案 3 :(得分:0)
看起来你已经得到了一两个合理的答案;我只想指出一个替代方案。虽然我在提及它时犹豫不决,std::valarray
非常适合我,但我无法抗拒:
std::valarray<int> x;
std::valarray<int> y;
// code to populate x and y elided
x += y;
有几个月(左右),我发现valarray
会变得如此简单,我发现真的很遗憾它已经丢失并被遗忘(然后我会想到像slice
,{{1}这样的事情。 },gslice
,slice_array
等,并希望我根本没有想到它。