0

イテレータを逆参照する必要があるのはなぜですか? たとえば、次のプログラムでは

#include <iostream>
#include <string>
#include <vector>

int main()
{
    using namespace std;
    string s("some string");

    for(auto it = s.begin(); it != s.end(); && !isspace(*it); ++it)
        *it = isupper(*it);
    cout<<s;
}

isupper(*it);ただの代わりに使用する必要があるのはなぜisupper(it);ですか?

4

3 に答える 3

11

Iterator は一般化されたポインターです。それは何かを指しています。「ポインター」自体ではなく、何か(この場合はcharまたはint)を必要とする関数がある場合は、イテレーターを逆参照する必要があります。

たとえば、標準advance関数はイテレータを引数として取ります。したがって、次のように、逆参照せずにイテレータを渡します。

std::advance(it, n);

しかし、int を指す反復子があり、その整数を 4 ずつ増やしたい場合は、

(*it) += 4;

C++ に関する優れた本を読むことをお勧めします。

ところで、ループ全体を変換への単一の呼び出しに置き換えることができます

 std::transform(s.begin(), s.end(), s.begin(), toupper);
于 2013-06-25T11:10:32.820 に答える
4

コードが実行するなど、イテレータ自体で操作を実行できる必要がありますit != s.end()++it

また、イテレータが指すオブジェクトに対して操作を実行できるようにする必要がある場合もあります。isupper(*it)

イテレータ自体ではなく、それが参照するものを参照したいことを示す操作が必要です。そうしないと、イテレータまたはそれらが指すものを比較しようとしているかどうかをコンパイラがどのように知るかをテスト するif (it == another_it)場合? ++it同じことが、それが指すものではなく、反復子を変更したい操作にも当てはまります。

イテレーターはget()、参照するものを返すメンバーを持つことができるのでisupper(it.get())、代わりに逆参照演算子をサポートします。これは、入力が少なく、ポインターと一貫性があり、イテレーターを必要とするすべてのコードでポインターを使用できるようにします。

于 2013-06-25T11:33:15.480 に答える
2

Pointer-to-T に対する操作とサブジェクト T に対する操作を区別するには、逆参照演算子が必要です。

例えば:

int* x = ...;

x++;

メモリ内の次の int を指すようにポインタをインクリメントしたいということですか? それとも、x が指す int をインクリメントしますか?

Deferenancing 演算子がないと、これはあいまいになります。

イテレータは、単純にポインタ インターフェイスを一般化したものです。

参照との対比:

int& x = ...;

x++;

参照には代替セマンティックがあり、逆参照は必要ありません。reference-to-T に対する操作は、サブジェクト T に適用されます。欠点は、参照自体を変更できないことです。

于 2013-06-25T12:14:33.230 に答える