1

STL コンテナーの一般的なパターンは次のとおりです。

map<Key, Value> map;
for(map<Key, Value>::iterator iter = map.begin(); iter != map.end(); ++iter)
{
  ...
}

したがって、テンプレート パラメーターの宣言を記述することを避けるために、次の場所でこれを行うことができます。

typedef map<Key, Value> TNiceNameForAMap;

しかし、このマップが単一の関数または単一の反復でのみ使用される場合、これは厄介なオーバーヘッドです。

この typedef を回避する方法はありますか?

4

7 に答える 7

10

「オーバーヘッド」の意味がわかりません。コードの記述方法が簡単になる場合はそれを使用し、それ以外の場合は手書きを使用します。

制限されたスコープでのみ使用する場合は、typedef を同じスコープに配置します。そうすれば、公開したり、文書化したり、UML 図に表示したりする必要はありません。例 (そして、これが他の点でこれまでで最高のコードであるとは主張しません):

int totalSize() {
    typedef std::map<Key, Value> DeDuplicator;
    DeDuplicator everything;

    // Run around the universe finding everything. If we encounter a key
    // more than once it's only added once.

    // now compute the total
    int total = 0;
    for(DeDuplicator::iterator i = everything.begin(); i <= everything.end(); ++i) {
        total += i->second.size(); // yeah, yeah, overflow. Whatever.
    }
    return total;
}

Ferruccio の提案 (ブーストを使用している場合) と組み合わせると、ループは次のようになります。

BOOST_FOREACH(DeDuplicator::pair p, everything) {
    total += p.second.size();
}

そして、bk1e の提案 (C++0x を使用している場合、またはその機能がある場合) と組み合わせて、互換性のある型への暗黙のキャストを通常は処理できるという事実に基づいて、BOOST_FOREACH が auto と対話する必要があると仮定します。 :

std::map<Key, Value> everything;
// snipped code to run around...
int total = 0;
BOOST_FOREACH(auto p, everything) {
    total += p.second.size();
}

悪くない。

于 2008-09-24T03:07:19.057 に答える
5

Boost.Foreachを使用できます

于 2008-09-24T03:13:41.837 に答える
3

C++ 標準の将来のバージョン ( C++0xとして知られる) では、キーワードの新しい使用法autoが導入され、次のようなものを記述できるようになります。

map<Key, Value> map;
for(auto iter = map.begin(); iter != map.end(); ++iter)
{
  ...
}
于 2008-09-24T03:39:50.713 に答える
2

個人的には、 MYMAP::iteratorはmap<int,string>::iteratorstd::map<int, std::string>::iteratorよりも読みやすいと思うので、常に typedef を実行します。唯一のオーバーヘッドは 1 行のコードです。

コードがコンパイルされると、実行可能ファイルのサイズや速度に違いはありません。あくまでも読みやすさです。

于 2008-09-24T03:14:05.360 に答える
0

過去数年間、私はSTLアルゴリズムを使用するよりも、手動で記述されたループを使用することから離れようとしました。上記のコードは次のように変更できます。

struct DoLoopBody {
  template <typename ValueType>
  inline void operator()(ValueType v) const {
    // ...
  }
};

std::for_each (map.begin(), map.end(), DoLoopBody ());

残念ながら、クラスDoLoopBodyをローカルクラスにすることはできません。これは、多くの場合、欠点として強調されています。ただし、これは、ループの本体を個別に単体テストできるという利点があると思います。

于 2008-09-24T07:54:10.023 に答える
0

C++0x では、範囲ベースの for ループも提供されます。これは、他の言語の繰り返しの for ループに似ています。

残念ながら、GCC は範囲ベースの for をまだ実装していません (ただし、auto は実装しています)

編集:その間、イテレータの型定義も検討してください。1回限りのtypedefを回避することはできませんが(常にオプションであるヘッダーにそれを入れない限り)、結果のコードは ::iterator 1つ分短くなります。

于 2008-09-24T04:59:58.943 に答える
0

typedef が単一の関数に対してローカルである場合、適切な名前である必要さえありません。テンプレートと同じように、X または MAP を使用します。

于 2008-09-24T03:58:22.383 に答える