std :: vector.at()それは参照またはコピーを返しますか?

私はC ++の学習を始めたばかりで、 std :: vector がどのように機能するかを試しています。

私はこのテストプログラムを持っています:

#include 
#include 

int main()
{
    std::vector element1 = { 1, 2,3 };
    std::vector element2 = { 4, 5, 6 };
    std::vector> lista = { element1, element2 };

    std::vector var = lista.at(0);

    for (std::vector::const_iterator i = var.begin(); i != var.end(); ++i)
        std::cout << *i << ' ';
    std::cout << std::endl;
    var[0] = 22;


    for (std::vector::const_iterator i = var.begin(); i != var.end(); ++i)
        std::cout << *i << ' ';
    std::cout << std::endl;


    for (std::vector::const_iterator i = lista.at(0).begin(); i != lista.at(0).end(); ++i)
        std::cout << *i << ' ';
    std::cout << std::endl;

    return 0;
}

それは出力します:

1 2 3
22 2 3
1 2 3

at演算子は参照を返さないと思います(しかし私は間違っているかもしれません)ので、新しいベクトルを返すと思いますか?

しかし、参照を取得したい場合は、どうすればいいですか?

UPDATE:

そして、コピーの代わりに listaelement1element2 の参照を取得する場合

6
ru de
@ S.Devしかし、それが参照を返す場合、なぜvarを変更した後にlistaに変更がないのでしょうか。
追加された 著者 VansFannel,
追加された 著者 S. Dev,

4 答え

at returns a reference (and a const reference for the const version).

Your issue is that you are taking an explicit value copy in your code with std::vector var = lista.at(0);. The obvious fix is auto& var = lista.at(0);.

最後に、 element1element2 の値のコピーを避けたい場合は、それらを削除して次のように記述します。

std::vector> lista = { { 1, 2,3 }, { 4, 5, 6 } };

代わりに。

Reference: http://en.cppreference.com/w/cpp/container/vector/at

10
追加された
つまり、参照を返しますが、その参照を std :: vector &変数ではなく std::vector 変数に格納すると、代わりに格納されます。参照にあるもののコピー?
追加された 著者 Nick A,
代わりに型エラーをスローしない特別な理由はありますか?
追加された 著者 Nick A,
ハハ、おそらくそれは愚かな質問でしたが、私が尋ねた直後に私はそれが std :: vector のために定義されたコピーコンストラクタのせいであろうと気づいた
追加された 著者 Nick A,
@ NickA:うん、C ++は一般にそのように動作します。値への参照をコピーすると、その参照の値コピーが作成されます。
追加された 著者 Bathsheba,
@ NickA:とても便利だから。
追加された 著者 Bathsheba,

at returns a reference.

You store it in a copy here std::vector var = lista.at(0);

You might do std::vector& var = lista.at(0); to get reference.

5
追加された
すばらしいです!!ありがとう。
追加された 著者 VansFannel,

at演算子は参照を返さないと思います(しかし私は間違っているかもしれません)

あなたは本当に間違っています。宣言に示すように、 vector :: at は参照を返します。

reference       at( size_type pos );
const_reference at( size_type pos ) const;

However, std::vector var is not a reference, and you copy initialize it from the returned reference.

しかし、参照を入手したい場合は、どうすればよいですか。

参照を取得するには、 at で返される参照を取得できる参照変数が必要です。

std::vector& var = lista.at(0);
//              ^ a reference

And also here, std::vector> lista = { element1, element2 };, I think there is a copy of element1 and element2 in lista vector.

そのとおり。

element1element2 のコピーを作成したくない場合は、どうすればよいですか。

ベクトル(のコピー)を外側のベクトルに格納したくない場合は、別のものを格納する必要があります。参照をコンテナに格納することはできませんが、 std :: reference_wrapper またはポインタを格納することはできます。例えば:

std::vector*> lista = { &element1, &element2 };

間接演算子を使用して、指示されたベクトルへの参照を取得できます。


あなたの例から何をしようとしているのかは明確ではありません、おそらくベクトルのベクトルを持つことは意味があり、代わりに element1element2 を参照にします。

std::vector> lista = {
    { 1, 2, 3 },
    { 4, 5, 6 },
};
std::vector& element1 = lista[0];
std::vector& element2 = lista[1];

サブベクトルの内容のコピーを避けたいだけで、後で element1element2 を使用したくない場合は、別の方法があります。 lista のサブベクトル

std::vector> lista = {
    std::move(element1),
    std::move(element2),
};
// element1 and elemenet2 are now in an unspecified state
3
追加された
OK。これで、なぜそれがコピーを取得しているのか理解できます。コピーコンストラクタだからです。ありがとうございます。
追加された 著者 VansFannel,
そしてここでも、 std :: vector > lista = {element1、element2};element1のコピーがあると思います。 lista ベクトルのcode> element2element1element2 のコピーを作成したくない場合は、どうすればいいですか。もっと良ければ、別の質問を作成できます。
追加された 著者 VansFannel,
私は lista ベクトル内のベクトルを再利用しようとしていますが、それらのコピーを作成しません。 N elementN ベクトルを作成し、それらを lista ベクトルに追加します。コピーや新しいベクトルを作成したくはありません。
追加された 著者 VansFannel,
しかし、この例は単なるテストです。 vector がどのように機能するのか知りたいと思いました。
追加された 著者 VansFannel,
ご回答ありがとうございます。私はそれについて多くのことを学びました。ところで、私は lista の中のベクトルを使います。息子の価値観を変えたり、すべての要素を新しいものに置き換えたりします。
追加された 著者 VansFannel,
@VansFannel編集を参照してください。元の質問の最後にフォローアップの質問を追加することができます。
追加された 著者 user2079303,

var is not a reference, its just another variable like b below.

int a = 5;
int b = a;
int &bref = a;
b=6;
cout<<

欲しいのは bref であり b ではありません。すなわち

std::vector &var = lista.at(0);
1
追加された