正如我在對您的問題發表評論時所說的,我認爲您的第一個解決方案是合理的。不過,我不確定給參數begin
是區分這兩種情況的最佳方法。主要的問題是你不能使用你的完整集合(包括本地主機成員)作爲範圍,這意味着你不能使用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
,這會擦除底層的迭代器類型。
你的第一個解決方案似乎很合適(在一種情況下將迭代器返回到第一個元素,在另一個情況下返回到第二個元素)。它可能不是最明確的方法,但它具有簡單的優點。如果你這樣做,我認爲解釋發生了什麼的一些評論會受到歡迎(明確指出第一個元素將始終與本地主機相對應,並正確記錄'begin'成員函數)。 –