17

開始イテレータと終了イテレータを取得するための関数を持つオブジェクトがあります。

const_iterator err_begin() const
const_iterator err_end() const 

それらにはbeginandという名前が付いていないためend、range-v3 の関数にオブジェクトを直接渡すことはできません。

このオブジェクトを range-v3 ライブラリで動作させるために使用できる単純なラッパーはありますか?

例えば:

auto hasErrors = !empty(something(x.err_begin(), x.err_end())); 
4

3 に答える 3

14

あなたが探しているように聞こえますiterator_range

auto hasErrors = !empty(ranges::make_iterator_range(x.err_begin(), x.err_end()));
于 2016-12-21T17:12:51.613 に答える
4

問題のクラスは、変更できないライブラリの一部であることを明確にしました。罰金。ファサード クラスを作成します。

class FacadeClass {

      const RealClassWithErrBeginEnd &r;

public:

      FacadeClass(const RealClassWithErrBeginEnd &r) : r(r) {}

      auto begin() const { return r.err_begin(); }
      auto end() const { return r.err_end(); }
};

これは、コンテナーを期待するほとんどのコードをだますのに十分なはずです。最悪の場合、ファサードに追加の typedef を提供する必要があるかもしれませんvalue_type

于 2016-12-21T17:10:42.063 に答える
1

boost::make_iterator_range正しいことをします。少し ADL を追加すると、1 つの自由な関数がすべての問題を解決することがわかります。

#include <vector>
#include <iostream>
#include <string>
#include <boost/range.hpp>


// simulate the library class
struct X
{
    auto err_begin() const { return errors.begin(); }
    auto err_end() const { return errors.end(); }

    std::vector<std::string> errors;

};

// provide a generator to build an iterator range
auto errors(const X& x)
{
    return boost::make_iterator_range(x.err_begin(), x.err_end());
}

// do things with the iterator_range
int main()
{
    X x;
    for (const auto& err : errors(x))
    {
        std::cout << err << std::endl;
    }

    std::cout << empty(errors(x)) << std::endl;
}
于 2016-12-21T17:18:28.060 に答える