如何从开始和结束迭代器创建范围?
How do I create a range from a begin and end iterator?
我有一个对象,其中包含用于获取开始和结束迭代器的函数:
const_iterator err_begin() const
const_iterator err_end() const
因为它们没有命名为 begin
和 end
,所以我无法将我的对象直接传递给 range-v3 中的函数。
是否有一个简单的包装器可用于使该对象与 range-v3 库一起使用?
例如:
auto hasErrors = !empty(something(x.err_begin(), x.err_end()));
您已阐明所涉及的 class 是您无法更改的库的一部分。美好的。创建门面 class:
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
,等等...
听起来你在找 iterator_range
:
auto hasErrors = !empty(ranges::make_iterator_range(x.err_begin(), x.err_end()));
boost::make_iterator_range
会做正确的事。现在添加一点 ADL,我们发现一个免费功能解决了我们所有的问题:
#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;
}
我有一个对象,其中包含用于获取开始和结束迭代器的函数:
const_iterator err_begin() const
const_iterator err_end() const
因为它们没有命名为 begin
和 end
,所以我无法将我的对象直接传递给 range-v3 中的函数。
是否有一个简单的包装器可用于使该对象与 range-v3 库一起使用?
例如:
auto hasErrors = !empty(something(x.err_begin(), x.err_end()));
您已阐明所涉及的 class 是您无法更改的库的一部分。美好的。创建门面 class:
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
,等等...
听起来你在找 iterator_range
:
auto hasErrors = !empty(ranges::make_iterator_range(x.err_begin(), x.err_end()));
boost::make_iterator_range
会做正确的事。现在添加一点 ADL,我们发现一个免费功能解决了我们所有的问题:
#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;
}