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?
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.
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.
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.
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.
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
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.
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 ofelement1
andelement2
inlista
vector.
That's right.
If I don't want to create a copy of
element1
andelement2
, 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_wrapper
s 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
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With