正如我在评论您的问题时所说,我认为您的第一个解决方案是合理的。但是,我不确定提供参数 tobegin
是区分这两种情况的最佳方法。这样做的主要问题是您不能将完整集合(包括 localhost 成员)用作范围,这意味着您不能使用Boost.Range 算法或基于 C++11 范围的 for 循环。
一个简单的解决方案是让两个不同的成员函数返回适当的范围,作为一对迭代器。Boost.Range 提供了一个sub_range
class,这似乎很合适(您想返回成员列表的子范围)。这是使用这种方法的示例代码:
#include <boost/range.hpp>
#include <iostream>
#include <string>
#include <vector>
struct MemberInfo
{
std::string name;
};
class MemberList
{
public:
typedef std::vector<MemberInfo>::iterator iterator;
typedef std::vector<MemberInfo>::const_iterator const_iterator;
MemberList()
: members_{MemberInfo{"local"}, MemberInfo{"foo"}, MemberInfo{"bar"}}
{}
boost::sub_range<std::vector<MemberInfo>> all() // includes localhost
{
return boost::sub_range<std::vector<MemberInfo>>(
members_.begin(), members_.end());
}
boost::sub_range<std::vector<MemberInfo> const> all() const
{
return boost::sub_range<std::vector<MemberInfo> const>(
members_.begin(), members_.end());
}
boost::sub_range<std::vector<MemberInfo>> some() // excludes localhost
{
return boost::sub_range<std::vector<MemberInfo>>(
++members_.begin(), members_.end());
}
boost::sub_range<std::vector<MemberInfo> const> some() const
{
return boost::sub_range<std::vector<MemberInfo> const>(
++members_.begin(), members_.end());
}
private:
std::vector<MemberInfo> members_;
};
现在,您可以使用其中一个all()
或some()
取决于是否要包含local
,并且两者都可以用作范围:
int main()
{
MemberList ml;
for (MemberInfo mi : ml.all()) { std::cout << mi.name << '\n'; }
for (MemberInfo mi : ml.some()) { std::cout << mi.name << '\n'; }
}
当然,您仍然可以照常使用迭代器:
std::find_if(ml.all().begin(), ml.all().end(), ...);
如果您不想泄露成员存储在 a 中的事实,则std::vector
可以使用any_range
,它会擦除底层迭代器类型。