I am working on a C 17 project and there i am using std::any
. A minimal reproducible example is given below for reference explaining what i want to achieve.
#include <any>
#include <vector>
#include <iostream>
int main()
{
std::vector<int> vec{1,2,3};
std::any anything = vec;
// anything.push_back(4);//i want to add an element into vector vec, using variable anything but this statement won't work
std::cout<<std::any_cast<std::vector<int>>(anything).size()<<std::endl;//prints 3
std::any_cast<std::vector<int>>(anything).push_back(4);//this adds(push_back) element into rvalue
std::cout<<std::any_cast<std::vector<int>>(anything).size()<<std::endl;//prints 3 but i want 4
}
As can be seen in the above example, i have a std::any
object and i am using std::any_cast
to add element into the vector. I want to add the element into the actual(lvalue
) vector named vec
but instead, the element is added into an rvalue
. Is there a way to add element into the vector named vec
using std::any
. If not then is there any other way of doing this like using std::variant
or something else that i may not be aware of. I am looking for a way of doing this in any version of C like C 11 or C 17 etc.
In my actual project, there is requirement for storing object of any type. So i got the same problem there. And then realized what is wrong(namely, we are using push_back
on an rvalue) and then i reduced the problem to a minimal reproducible example and am asking here.
CodePudding user response:
we are using push_back on an rvalue
No, that's not the problem. any
stores a copy of what it is given. It doesn't reference some other object. It creates an object from what it is given. So even if you get a reference to the object in the any
, it wouldn't be a reference to vec
itself.
If you want to store a reference to an object in an any
, you need to do so explicitly by storing either a pointer or a reference_wrapper
to that object:
using ref_type = decltype(std::ref(vec));
std::any anything = std::ref(vec);
std::any_cast<ref_type>(anything).get().push_back(4);
Note that having an any
which references an object is dangerous. If the any
outlives the lifetime of the referenced object, you'll get bad things when you try to access the referenced object. This is part of why any
stores copies by default.
CodePudding user response:
You miss a reference:
std::any_cast<std::vector<int>&>(anything).push_back(4);
// ^
Currently, you create copy with the std::any_cast
.
Note:
As pointed by Nicol Bolas, that only avoid copy for the cast, but the copy of the initial std::vector
into the std::any
is not avoided.