我有一个类,成员列表,其中包含{member}的{member}信息。这些代表了网络上的同伴。
我使用该类向列表中添加一些功能。
我想暴露一些迭代器(开始和结束),以便外部代码可以遍历我的内部列表并读取它们的数据。但是,我想有两种方法 - 一种包含localhost的元素,另一种不包含。
这样做的好方法是什么?
我可以先放置本地节点,然后像std::list
那样只给第二个元素而不是第一个元素。或者有人建议存放一对bool,如果它是本地的话。
有关良好方法的任何建议吗?我对高级begin(showlocal=false)
的东西还不太好。
答案 0 :(得分:4)
就我个人而言,我会以不同的方式处理这个问题,让你的memberinfo
有办法告诉你它是否是本地的。
这样,由于所包含对象的特化,您不会专门化您的集合类。实际上,您可以使用标准std::list<memberinfo>
。
E.g。
class memberinfo
{
bool IsLocal( ) const;
}
然后,当您迭代所包含的对象时,您会选择是否对本地成员感兴趣。
E.g。
std::list<memberinfo>::iterator it;
std::list<memberinfo> list;
for ( it = list.begin() ; it != list.end() ; it++ )
{
if ( it->IsLocal() )
{
// blah blah blah
}
else
{
// dum dee dum dee
}
}
答案 1 :(得分:0)
正如我在评论中所说,我认为你的第一个解决方案是合理的。但是,我不确定为begin
提供参数是区分这两种情况的最佳方法。这个问题的主要问题是你不能将你的完整集合(包括localhost成员)用作范围,这意味着你不能使用Boost.Range algorithms或基于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(), ...);
如果您不想泄露成员存储在std::vector
中的事实,可以使用any_range
来删除底层迭代器类型。