web-dev-qa-db-ja.com

なぜstd :: copy_ifアルゴリズムがないのですか?

C++でstd :: copy_ifアルゴリズムを使用しない特別な理由はありますか? std :: remove_copy_ifを使用して必要な動作を実現できることはわかっています。私はそれがC++ 0xで来ていると思いますが、範囲、出力イテレータ、ファンクタを取る単純なcopy_ifはいいでしょう。それは単に見逃されただけでしたか、それとも背後に他の理由がありますか?

63
Naveen

Stroustrupの「C++プログラミング言語」によると、それは見落としに過ぎませんでした。

(引用として、boost mail-listsで回答された同じ質問: copy_if

41
sbk

Stroustrupはそれを忘れたと言います。それはC++ 11にあります。

ただし、remove_copy_if(実際にはcopy_if_not) に加えて not1代わりに。

27
rlbond

完全を期すために、誰かがこの質問に彼/彼女の方法をググる場合、それが今(C++ 11の後)あるa copy if アルゴリズム。期待どおりに動作します(一部の述語がtrueを返す範囲内の要素を別の範囲にコピーします)。

典型的なユースケースは

std::vector<int> foo{ 25, 15, 5, -5, -15 };
std::vector<int> bar;

// copy only positive numbers:
auto it = std::copy_if (foo.begin(), foo.end(), std::back_inserter(bar), 
            [](int i){return !(i<0);
          });
9

Multiplesourcesindicate 誤ってSTLから除外された。

しかし、それが事実なのか、それとも永遠に続く神話なのかはわかりません。誰かがインターネット上のランダムな投稿へのリンクよりも信頼できるソースを指摘してくれるとありがたいです。

7
Alex B

自分で書くのはとても簡単です:

template <class InputIterator, class OutputIterator, class Predicate>
OutputIterator copy_if(InputIterator first, InputIterator last,
                       OutputIterator result, Predicate pred)
{
  return std::remove_copy_if(first,last,result,std::not1(pred));
}

編集:このバージョンはすべての述語で機能します。

template <class InputIterator, class OutputIterator, class Predicate>
OutputIterator copy_if(InputIterator first, InputIterator last,
                       OutputIterator result, Predicate pred)
{
  while(first!=last)
  {
    if(pred(*first))
        *result++ = *first;
    ++first;
  }
  return result;
}
7
alex tingle

完全を期すために、boost::algorithm::copy_ifでc ++ 11のバージョン(私など)を使用できない boost/algorithm/cxx11/copy_if.hpp を使用できない人のために、ブーストにstd::copy_ifを追加しますいつ:

#if __cplusplus >= 201103L
//  Use the C++11 versions of copy_if if it is available
using std::copy_if;         // Section 25.3.1
#else

例:

#include <boost/algorithm/cxx11/copy_if.hpp>
#include <boost/assign/list_of.hpp> // for 'list_of()'
#include <boost/foreach.hpp>

#include <iostream>
#include <vector>
#include <iterator>

struct Odd
{
  bool operator()(int n)
  {
    return n & 1;
  }
};

int main()
{
  std::vector<int> v = boost::assign::list_of(0)(1)(2)(3)(4);
  BOOST_FOREACH(int i, v)
    std::cout << i << ' ' ;

  std::vector<int> out;
  boost::algorithm::copy_if(v.begin(), v.end(), std::back_inserter(out), Odd());

  std::cout << std::endl;

  BOOST_FOREACH(int i, out)
    std::cout << i << ' ' ;

}

出力:

0 1 2 3 4 
1 3 
1
Patryk