就地施工回位失败
Emplace back fails at in place construction
我有一个对象,我只想构造一次,因为它所在的 class 通过向它们添加原始指针来跟踪它的对象。内联构建它似乎失败了:
// Defined utilities:
ModuleClusterPlot(Type typeArg, const int& layer, const int& module, const int& ladder, const int& startEventArg, const int& endEventArg);
~ModuleClusterPlot();
// Invalid utilities
ModuleClusterPlot(ModuleClusterPlot& t_other) = delete;
ModuleClusterPlot(ModuleClusterPlot&& t_other) = delete;
ModuleClusterPlot& operator=(const ModuleClusterPlot& t_other) = delete;
ModuleClusterPlot& operator=(ModuleClusterPlot&& t_other) = delete;
通过 emplace back 调用构造函数失败,因为它试图调用移动构造函数(为什么?):
moduleClusterPlots.emplace_back(t_type, t_layer, t_module, t_ladder, i, i);
我在这里做错了什么?我正在使用 gcc 7.1.0
和 std=c++14
标志。
最小示例:
#include <vector>
class ModuleClusterPlot
{
public:
enum Type
{
foo = 0,
bar
};
ModuleClusterPlot(Type typeArg);
~ModuleClusterPlot();
// Invalid utilities
ModuleClusterPlot(ModuleClusterPlot& t_other) = delete;
ModuleClusterPlot(ModuleClusterPlot&& t_other) = delete;
ModuleClusterPlot& operator=(const ModuleClusterPlot& t_other) = delete;
ModuleClusterPlot& operator=(ModuleClusterPlot&& t_other) = delete;
};
int main()
{
std::vector<ModuleClusterPlot> collection;
collection.emplace_back(ModuleClusterPlot::foo);
}
如何防止在此处调用移动构造函数?
您违反了 emaplce_back
的约束。如果我们从 [sequence.reqmts] 查看 table 101,我们有
Requires: T shall be EmplaceConstructible into X from args. For vector, T shall also be MoveInsertable into X.
强调我的
因为你的 class 不是 move insertable 它不能与 emplace_back
一起使用。
之所以需要这样做是因为 size()
变得大于 capacity()
然后向量需要分配新存储并将元素移动到新存储。如果它不能做到这一点,那么向量就不能按预期运行。
std::vector<T>::emplace_back
需要移动构造函数或复制构造函数。原因是它可能需要重新分配内存和 move/copy 现有对象到新缓冲区。
即使您只在空向量上调用它,实际上不需要移动任何现有对象,请记住,相同的函数 emplace_back
可用于空向量和非空向量。该函数不可能仅从空状态知道它正在被使用,因此在实例化成员函数时,处理非空向量的代码也必须有效。
我有一个对象,我只想构造一次,因为它所在的 class 通过向它们添加原始指针来跟踪它的对象。内联构建它似乎失败了:
// Defined utilities:
ModuleClusterPlot(Type typeArg, const int& layer, const int& module, const int& ladder, const int& startEventArg, const int& endEventArg);
~ModuleClusterPlot();
// Invalid utilities
ModuleClusterPlot(ModuleClusterPlot& t_other) = delete;
ModuleClusterPlot(ModuleClusterPlot&& t_other) = delete;
ModuleClusterPlot& operator=(const ModuleClusterPlot& t_other) = delete;
ModuleClusterPlot& operator=(ModuleClusterPlot&& t_other) = delete;
通过 emplace back 调用构造函数失败,因为它试图调用移动构造函数(为什么?):
moduleClusterPlots.emplace_back(t_type, t_layer, t_module, t_ladder, i, i);
我在这里做错了什么?我正在使用 gcc 7.1.0
和 std=c++14
标志。
最小示例:
#include <vector>
class ModuleClusterPlot
{
public:
enum Type
{
foo = 0,
bar
};
ModuleClusterPlot(Type typeArg);
~ModuleClusterPlot();
// Invalid utilities
ModuleClusterPlot(ModuleClusterPlot& t_other) = delete;
ModuleClusterPlot(ModuleClusterPlot&& t_other) = delete;
ModuleClusterPlot& operator=(const ModuleClusterPlot& t_other) = delete;
ModuleClusterPlot& operator=(ModuleClusterPlot&& t_other) = delete;
};
int main()
{
std::vector<ModuleClusterPlot> collection;
collection.emplace_back(ModuleClusterPlot::foo);
}
如何防止在此处调用移动构造函数?
您违反了 emaplce_back
的约束。如果我们从 [sequence.reqmts] 查看 table 101,我们有
Requires: T shall be EmplaceConstructible into X from args. For vector, T shall also be MoveInsertable into X.
强调我的
因为你的 class 不是 move insertable 它不能与 emplace_back
一起使用。
之所以需要这样做是因为 size()
变得大于 capacity()
然后向量需要分配新存储并将元素移动到新存储。如果它不能做到这一点,那么向量就不能按预期运行。
std::vector<T>::emplace_back
需要移动构造函数或复制构造函数。原因是它可能需要重新分配内存和 move/copy 现有对象到新缓冲区。
即使您只在空向量上调用它,实际上不需要移动任何现有对象,请记住,相同的函数 emplace_back
可用于空向量和非空向量。该函数不可能仅从空状态知道它正在被使用,因此在实例化成员函数时,处理非空向量的代码也必须有效。