0

(同じ長さの) 2 つのベクトルを取り、それらを値で加算するバイナリ関数を作成しようとしています。何らかの理由で、次のコードは機能しません。

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;
  }
};

明らかに、2 番目のバージョンは時間がかかります (追加のベクターをコピーする必要があるため)。入力が定数ベクトルだからですか?もしそうなら、それが必要な理由はありますか?この関数を boost::mpi の allreduce() 関数への入力として使用することを計画していることに注意してください。

4

4 に答える 4

4

そのまま定義ityvector::iterator yconst、 を返します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-correctnessを壊す可能性があるため、constコンテナで非constイテレータを使用できないことです。std::vector<int>::const_iterator2番目の引数で使用する必要があります。

それ以外は、最初のブロックの実装は、あなたが主張することを実行しません。コンテナを反復処理し、格納された値を使用してコンテナにインデックスを付け、そこで更新します。実際に2つのコンテナーから値を追加する場合は、それよりもはるかに簡単です。

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

すでに妥当な答えが 1 つまたは 2 つ得られているようです。代替案を指摘します。私はそれについて言及するのをためらっていますがstd::valarray、これにとてもよく合い、私は抵抗できません:

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

// code to populate x and y elided

x += y;

数か月ごとに (またはそれくらい) 何かvalarrayが非常に単純になり、それが失われたり忘れられたりするのは本当に残念だと思います (そのときslicegsliceslice_arrayindirect_array、 などのことを考え、まったく考えなければよかったと思います) )。

于 2012-04-24T17:45:34.493 に答える
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 に答える