I have a class which contains a constructor which moves an object during its construction:
class SomeClass
{
private:
const std::unique_ptr<Base> foo;
public:
template <typename T>
inline explicit SomeClass(T&& derived) noexcept
: foo(std::make_unique<T>(derived))
{
static_assert(std::is_base_of<Base, T>::value);
}
};
The an object of the class can be constructed without issue when I require only a single instance:
class Derived : public Base
{
// ...
};
Derived bar(...);
SomeClass baz(std::move(bar));
// Or
SomeClass baz(Derived(...));
However I am unable to emplace (or push) any objects of type SomeClass to a std::vector<SomeClass>.
std::vector<SomeClass> vec;
Derived bar(...);
vec.emplace_back(std::move(bar)); // Does not work.
vec.emplace_back(Derived(...)); // Does not work.
Please could you explain why objects can not be emplaced? I thought that the perfect forwarding that emplace_back used would allow construction of an instance of SomeClass inplace in the same way that a single instance could be constructed.
Please could you also explain how things might be modified to allow construction of a std::vector<SomeClass>?
My guess is that as constructor arguments are passed by move, then they are not being forwarded all the way to the constructor within the emplace_back method.
std::vector::emplace_backimposes the following requirements onvalue_type:A
constmember of a class implicitly deletes move constructor, i.e.SomeClassis notMoveInsertablebecause ofconst std::unique_ptr<Base> foo.Solution: remove
constfromfoo.Live example.
As a side note, I would suggest to make
noexceptconditional depending onstd::is_nothrow_constructible(1) and passstd::forward<T>(derived)tostd::make_uniqueto utilise forwarding reference (2).