I often prefer to use references than pointers whenever possible, it makes the syntax cleaner in my opinion. In this case, I have a class:
class Foo
{
public:
Foo(Bar & bar) : bar_(bar) {}
private:
Bar & bar_;
};
operator=()
is implicitely deleted by the compiler for such a class, since once a reference is set, it cannot be changed (I can technically define my own that doesn't change bar_, but this would not be the required behaviour, so I'd rather the compiler complain if I try to assign a foo).
What I need is a std::vector<Foo> v;
. This is impossible before C++11, since the template parameter must to be CopyAssignable. Indeed, when I call v.push_back(Foo(bar));
, the compiler complains. But I feel it could be possible since C++11 and Move semantics.
My question is: is there a workaround using C++11 that would make building such a vector possible, or am I stuck in this case and have no way around using pointers instead of references? If there's a workaround, I'd highly appreciate a code snippet since I'm unfamiliar with move semantics.
The template parameter of a container doens't have to be CopyAssignable, it depends on what operations you perform on your container, and if you really use operation that requires CopyAssignable or MoveAssignable, you cannot use a reference as you wish (even with move semantic). But if you use only other operations (see standard), it will be fine. Some operations only needed CopyInsertable, MoveInstable and/or EmplaceConstructible.
Voila
emplace_back
is able to do the job because of perfect forwarding.You can also store a reference by itself in a container with
std::reference_wrapper
used likestd::vector<std::reference_wrapper<int>> v
Use
v.emplace_back(bar)
instead ofpush_back
. It will construct aFoo
in place in the memoryvector
has allocated for it, thus requiring no copying. Just passemplace_back
the arguments to construct aFoo
.