Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::vector.at(). Does it return a reference or a copy?

Tags:

c++

stdvector

I've just started learning C++ and I'm trying how std::vector works.

I have this test program:

#include <iostream>
#include <vector>

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

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

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


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


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

    return 0;
}

That outputs:

1 2 3
22 2 3
1 2 3

I think that at operator doesn't return a reference (but maybe I'm wrong), so I think it returns a new vector, isn't it?

But, if I want to get a reference, how can I do it?

UPDATE:

And... if I want to get in lista the references of element1 and element2 instead of a copy?

like image 371
VansFannel Avatar asked Apr 20 '18 09:04

VansFannel


People also ask

What is std vector in C++?

std::vector (for T other than bool) meets the requirements of Container, AllocatorAwareContainer, SequenceContainer, ContiguousContainer (since C++17) and ReversibleContainer. Member functions of std::vector are constexpr : it is possible to create and use std::vector objects in the evaluation of a constant expression.

What is a reference in a vector?

The element at the specified position in the vector. If the vector object is const-qualified, the function returns a const_reference. Otherwise, it returns a reference. Member types reference and const_reference are the reference types to the elements of the container (see vector member types ). Constant.

What is the use of return function in vector?

Returns a reference to the element at position n in the vector container. A similar member function, vector::at, has the same behavior as this operator function, except that vector::at is bound-checked and signals if the requested position is out of range by throwing an out_of_range exception.

How to swap the contents of one vector with another vector?

Check if the position is divisible by 2, if yes, print the element at that position. This function is used to swap the contents of one vector with another vector of same type and sizes of vectors may differ. vectorname1.swap (vectorname2) Parameters: The name of the vector with which the contents have to be swapped.


4 Answers

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<int> var = lista.at(0);. The obvious fix is auto& var = lista.at(0);.

Finally, if you wish to avoid a value copy of element1 and element2, you can remove them and write

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

instead.

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

like image 153
Bathsheba Avatar answered Nov 01 '22 05:11

Bathsheba


at returns a reference.

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

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

like image 27
Jarod42 Avatar answered Nov 01 '22 05:11

Jarod42


I think that at operator doesn't return a reference (but maybe I'm wrong)

You're wrong indeed. vector::at returns a reference, as shown in the declaration:

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

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

But, if I want to get a reference, how can I do it?

To get a reference, you need a reference variable where you can capture the reference returned by at:

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

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

That's right.

If I don't want to create a copy of element1 and element2, what do I have to do?

If you don't want to store (copies of) vectors in the outer vector, then you need to store something else. You cannot store references in containers, but you can store std::reference_wrappers or pointers. For example:

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

You can then get a reference to the pointed vector using the indirection operator.


It's not clear from your example what you're trying to do, perhaps it might make sense to have a vector of vectors, and let element1 and element2 be references instead:

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

If you only want to avoid copying contents of the subvectors, and if you don't intend to use element1 and element2 afterwards, then there is another way: You can move construct the subvectors of lista:

std::vector<std::vector<int>> lista = {
    std::move(element1),
    std::move(element2),
};
// element1 and elemenet2 are now in an unspecified state
like image 38
eerorika Avatar answered Nov 01 '22 04:11

eerorika


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

int a = 5;
int b = a;
int &bref = a;
b=6;
cout<<a<<endl; // a is still 5
bref = 6;
cout<<a<<endl; // a is now 6

What you want is bref and not b ie

std::vector<int> &var = lista.at(0);
like image 21
Gaurav Sehgal Avatar answered Nov 01 '22 04:11

Gaurav Sehgal