就地施工回位失败

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.0std=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 可用于空向量和非空向量。该函数不可能仅从空状态知道它正在被使用,因此在实例化成员函数时,处理非空向量的代码也必须有效。