I want to store a list of objects in an std::vector
, but the objects contain a reference and cannot be assigned to. I can, however, copy-construct the object.
The only option I can think of is to use pointers to wrap the objects and reseat the pointers when they need to be assigned, but the syntax for this would significantly reduce readability, especially when using iterators, and I would prefer an alternative.
Doesn't work:
std::vector<MyObject> myVector;
//fill the vector
//...
myVector[1] = object1;
Smart pointers sacrifice readability:
std::vector<std::unique_ptr<MyObject>> ptrVector;
//fill the vector
//...
ptrVector[1] = std::unique_ptr<MyObject>(new MyObject(object1));
Are there any other methods to use unassignable objects in an std::vector
?
This isn't a direct answer to your question as I can't offer a replacement for std::vector
, or a different way of using it that allows you to do what you need to.
However, if it is possible to modify the definition of MyObject
, it may be an option to change it so it uses std::reference_wrapper
instead of conventional references. That would allow MyObject
to be assignable.
Example:
#include <vector>
#include <functional>
#include <iostream>
struct MyObject
{
//int &_i;
std::reference_wrapper<int> _i;
MyObject(int &i):_i(i) {}
};
int main() {
std::vector<MyObject> vec;
int i1 = 3;
int i2 = 4;
MyObject c1(i1);
MyObject c2(i2);
/* Storing object. */
vec.push_back(c1);
/* Assigning to it. */
vec[0] = c2;
/* Confirming that it's the correct object now. */
for (const MyObject &it : vec)
std::cout << it._i << std::endl;
/* Modifying the value of its internal reference. */
vec[0]._i.get() = 5;
/* Confirming that the original int changed value indeed. */
std::cout << "i2 == " << i2 << std::endl;
return 0;
}
Caveat: Existing code may already contain direct assignments to the reference member (i.e. the member called _i
in the code above). Those assignments were intended to change the value of the object the reference refers to. When replacing the reference with a std::reference_wrapper
, all direct assignments _i = x
must be replaced with _i.get() = x
, otherwise the semantics of the program change entirely.
(EDIT) If the references used are const-references const T&
, a std::reference_wrapper<const T>
can be used. Using the example above, the definition of MyObject
then changes to this:
struct MyObject
{
std::reference_wrapper<const int> _i;
MyObject(const int &i):_i(i) {}
};
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