0

今、《C++ 標準ライブラリ》を読んでいるのですが、5.7 章で何か混乱しているのを見つけました。ご存知のように、コレクションの要素を処理する独自の関数とアルゴリズムを作成できます。もちろん、これらの操作は一般的なものでもかまいません。例を見てみましょう。次のコードは、渡されたコンテナのすべての要素が後に続くオプションの文字列を出力する汎用関数を定義します。

template <class T>
inline void PRINT_ELEMENTS(const T& col1,const char *optcstr = "")
{
    typename T::const_iterator pos;
    for(pos = col1.begin();pos != col1.end();++pos)
        cout << *pos << " ";
    cout << endl;
}

pos は、渡されたコンテナー型のイテレーター型を持つと宣言されています。typyname は、const_iterator型であり、型 T の値ではないことを指定する必要があります。

いくつか質問があります:

(1)コード中のtypenameを消すとうまくいきます。次のコードを参照してください。

#include <iostream>
#include <vector>
#include <set>
#include <algorithm>

using namespace std;

int square (int value)
{
    return value*value;
}

template <class T>
inline void PRINT_ELEMENTS(const T& col1,const char *optcstr = "")
{
    /*typename T::const_iterator pos;*/
    T::const_iterator pos;

    for(pos = col1.begin();pos != col1.end();++pos)
        cout << *pos << " ";
    cout << endl;
}

int main()
{
    set<int>    coll1;
    vector<int> coll2;

    // insert elements from 1 to 9 into coll1
    for (int i=1; i<=9; ++i) {
        coll1.insert(i);
    }
    /*PRINT_ELEMENTS(coll1,"initialized: ");*/

    // transform each element from coll1 to coll2
    // - square transformed values
    transform (coll1.begin(),coll1.end(),    // source
                    back_inserter(coll2),    // destination
                    square);                      // operation

    PRINT_ELEMENTS(coll2,"squared:     ");
}

それはうまく機能します。その出力は次のとおりです。 ここに画像の説明を入力

typenameは必要ないのですか? そして、私はここでその機能をよく理解していません。誰かが私に通訳してもらえますか?

(2) vector::iterator を使用して、次のような要素を出力できなかったのはなぜですか。

#include <iostream>
#include <set>
#include <vector>
#include <algorithm>
using namespace std;

int main()
{
    set<int> intSet;
    vector<int> intVector2;

    for (int i = 1;i <= 10;++i)
        intSet.insert(i);

    transform(intSet.begin(),intSet.begin(),
        back_inserter(intVector2),
        negate<int>());

    vector<int>::iterator iter = intVector2.begin();
    for(;iter != intVector2.end();++iter)
        cout << *iter << endl;
}

Visual Studio 2008 を使用してコードを実行しています。誰か助けてくれませんか? どうもありがとう。

4

2 に答える 2

4

typenameVisual Studio の一部のバージョンは標準に準拠していないため、必要ありません。新しいバージョンや他のコンパイラはこれに関してより厳密であり、コードはそれなしではコンパイルに失敗します。

begin()andbegin()ではなくbegin()andを渡したため、2 番目の例は機能しませんend()

transform(intSet.begin(),intSet.begin(),

おっと。

于 2012-04-07T13:03:58.483 に答える
0

(1)

typename は、特定の状況でそのオペランドを型として明確にするのに役立ちます。

最も顕著なのは、クラス宣言のスコープ内にあるようです。

class X
{
    ...
    typename Y::Z w; // necessary
};

(2)

誤字脱字あり…

-    transform(intSet.begin(),intSet.begin(),
    back_inserter(intVector2),
    negate<int>());


+    transform(intSet.begin(),intSet.end(),
    back_inserter(intVector2),
    negate<int>());
于 2012-04-07T13:00:06.363 に答える