8

次の操作を実行するための効率的で慣用的な方法はありますか?

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()、 を使用するだけで済み+ません+=。標準ライブラリに、冗長性を持たずにイテレータを使用できるアルゴリズムがありますか、または完全なループを手動で作成する必要がありますか?

4

6 に答える 6

4

の冗長性の何が問題になっています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;
}
于 2013-09-17T18:51:46.903 に答える
2

それを「慣用的」と呼ぶかどうかはわかりませんが、

assert(a.size()==b.size());
auto bi = b.begin();
for (auto& i : a) {
  i += *(bi++);
}

かなり簡潔です。

于 2013-09-17T18:52:52.570 に答える
1

探していた種類のジェネリック関数が見つからず、最終的に名前を付けた次の関数を使用しましたrange_map(「指定された関数を2つの指定された範囲で要素ごとにマップする」)。コメントが指摘するように、実際にはバイナリに過ぎません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>());

function の単項版もありrange_map、特定のファンクターを範囲にマップします。

template<class InputIt, class BinaryOperation>
void range_map(InputIt first, InputIt last,
               UnaryOperation unary_op)
{
    while (first != last) {
        unary_op(*first1++);
    }
}
于 2013-09-17T20:50:33.537 に答える
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;
}
于 2013-09-18T05:41:10.073 に答える