0

我正在尝试编写一个二进制函数,该函数采用两个向量(长度相同)并将它们按值相加。由于某种原因,以下代码不起作用:

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() 函数的输入,如果这有什么不同的话

4

4 回答 4

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>());
于 2012-04-24T17:07:09.643 回答
1

错误是您不能将非常量迭代器与 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;
   }
};
于 2012-04-24T17:08:20.530 回答
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;
}
于 2012-04-24T17:12:05.650 回答
0

看起来你已经得到了一个或两个合理的答案;我只是指出一个替代方案。尽管我不愿提及它,但它std::valarray非常适合我,我无法抗拒:

std::valarray<int> x;
std::valarray<int> y;

// code to populate x and y elided

x += y;

每隔几个月(左右),我就会看到一些事情valarray变得如此简单,我发现它被遗失和遗忘真的很遗憾(然后我想到诸如slice, gslice, slice_array,indirect_array等之类的事情,并希望我根本没有想到它)。

于 2012-04-24T17:45:34.493 回答