为包装列表自定义迭代器
Customize an iterator for a wrapped list
我有一个类memberlist,它包含类memberinfo的std::list
。这些表示网络上的对等体。
我使用该类向列表中添加一些功能。
我想公开一些迭代器(begin和end),这样外部代码就可以在我的内部列表中循环并读取它们的数据。然而,我希望有两种方法来实现这一点——一种方法包括localhost的元素,另一种方法不包括。
做这件事的好方法是什么?
我可以先放本地节点,然后像begin(showlocal=false)
一样只给第二个元素,而不是第一个元素。或者有人建议存储一双bool,并说明它是本地的还是非本地的。
有什么好方法的建议吗?我还不太擅长高级STL
的东西。
就我个人而言,我会用不同的方式来处理这个问题,并让您的memberinfo
有一种方法来告诉您它是否是本地的。
这样一来,由于所包含对象的专业化,您就不会专门化您的收藏类。事实上,您可以使用标准的std::list<memberinfo>
。
例如
class memberinfo
{
bool IsLocal( ) const;
}
然后,在遍历包含的对象时,您可以选择是否对本地成员感兴趣。
例如
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
}
}
正如我在评论您的问题时所说,我认为您的第一个解决方案是合理的。然而,我不确定给begin
一个参数是否是区分这两种情况的最佳方法。这方面的主要问题是,您不能将整个集合(包括localhost成员)用作范围,这意味着您不能使用Boost.range算法或基于C++11范围的for循环。
一个简单的解决方案是让两个不同的成员函数作为一对迭代器返回适当的范围。Boost.Range提供了一个sub_range
类,这似乎很合适(您希望返回成员列表的子范围)。以下是使用这种方法的示例代码:
#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
,它会擦除底层迭代器类型。
- 跟随整数索引列表的自定义类迭代器
- 如何在创建自定义迭代器时获得 std::p air 的第一个和第二个?
- 自定义 STL 兼容迭代器,用于迭代 2D 数组类的列
- 无法使用自定义迭代器进行排序
- 比较迭代器会使程序崩溃,而不会在自定义气泡排序实现中出现错误
- 使用迭代器的自定义比较器函数
- 具有迭代器和自定义步长的循环结束条件
- 在C++中使用带有自定义向量的迭代器
- 指向临时对象的自定义迭代器(延迟加载)
- MSVC++ 17 std::copy 期望自定义迭代器的"operator -"
- 如何使用提升范围将自定义迭代器封装在函数中
- 字符串反向迭代器自追加的持久性
- 如何将 std::num_put 与自定义迭代器一起使用?
- 自定义迭代器:如果 a 和 b 的行为不同,如何正确处理距离计算和相等比较
- 迭代器关系运算符出错(带单独链接和迭代器的自定义哈希表)
- std::sort 在我的自定义迭代器上不起作用
- 为自定义数组实现迭代器
- C++自定义惰性迭代器
- 奇怪的编译器错误,说明我的迭代器未定义
- c++迭代器操作符定义