我有一个类,其中包含一个构造函数,该构造函数在构造过程中 move 对象:
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);
}
};
当我只需要一个实例时,可以毫无问题地构造该类的对象:
class Derived : public Base
{
// ...
};
Derived bar(...);
SomeClass baz(std::move(bar));
// Or
SomeClass baz(Derived(...));
但是,我无法将 SomeClass 类型的任何对象放置(或推送)到 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.
请您解释一下为什么无法放置物体?我以为完美转发了emplace_back
使用将允许构造 SomeClass
的实例以与构造单个实例相同的方式就位。
请您也解释一下如何修改以允许构建 std::vector<SomeClass>
?
我的猜测是,由于构造函数参数是通过 move 传递的,因此它们不会一直转发到 emplace_back
内的构造函数。方法。
最佳答案
std::vector::emplace_back
对 value_type
提出以下要求:
Type requirements
-
T
(the container's element type) must meet the requirements ofMoveInsertable
andEmplaceConstructible
.
一个const
类的成员隐式删除 move 构造函数,即 SomeClass
不是MoveInsertable
因为const std::unique_ptr<Base> foo
.
解决方案:删除const
来自foo
.
struct Base {};
struct Derived : public Base {};
class SomeClass
{
private:
std::unique_ptr<Base> foo;
public:
template <typename T>
inline explicit SomeClass(T&& derived)
noexcept(std::is_nothrow_constructible_v<decltype(foo), T&&>) // (1)
: foo(std::make_unique<T>(std::forward<T>(derived))) // (2)
{
static_assert(std::is_base_of<Base, T>::value);
}
};
int main()
{
std::vector<SomeClass> vec;
Derived bar{};
vec.emplace_back(std::move(bar));
vec.emplace_back(Derived{});
}
作为旁注,我建议制作 noexcept
有条件取决于 std::is_nothrow_constructible
(1)并通过std::forward<T>(derived)
至std::make_unique
使用转发引用 (2)。
关于c++ - 创建 move 构造对象的 vector ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52415574/