1

クラス memberinfoを含むstd::listクラス memberlist があります。これらは、ネットワーク上のピアを表します。

このクラスを使用して、いくつかの機能をリストに追加します。

外部コードが内部リストをループしてデータを読み取れるように、いくつかの反復子 (開始と終了) を公開したいと考えています。ただし、これを行うには 2 つの方法が必要です。1 つはローカルホストの要素を含む方法で、もう 1 つは含まない方法です。

これを行う良い方法は何ですか?

最初にローカル ノードを配置してbegin(showlocal=false)から、最初の要素ではなく 2 番目の要素を指定することもできます。または、ローカルかどうかを示す bool を使用して のペアを保存することを誰かが提案しました。

これを行うための良い方法に関する提案はありますか? 私はSTLまだ高度なものについてはあまり得意ではありません。

4

2 に答える 2

4

個人的には、これに別の方法でアプローチし、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
    }
}
于 2012-09-14T14:47:38.743 に答える
0

あなたの質問へのコメントで述べたように、あなたの最初の解決策は合理的だと思います。ただし、パラメータを に与えることbeginが、2 つのケースを区別するための最良の方法であるかどうかはわかりません。これに関する主な問題は、完全なコレクション (localhost メンバーを含む) を範囲として使用できないことです。つまり、Boost.Range アルゴリズムまたは C++11 の範囲ベースの for ループを使用できません。

簡単な解決策は、適切な範囲を返す 2 つの異なるメンバー関数をイテレータのペアとして持つことです。Boost.Range はsub_rangeclassを提供しますが、これはかなり適切と思われます (メンバーのリストのサブ範囲を返したい場合)。このアプローチを使用したサンプル コードを次に示します。

#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。これにより、基になる反復子の型が消去されます。

于 2012-09-14T16:09:29.050 に答える