2

我无法编译以下dont_compile函数。我不明白为什么它不起作用。但是,它确实适用于list.

class Thing {
public:
    Thing() {}
    Thing(const Thing &) = delete;
};

int dont_compile(int argc, char ** argv)
{
    std::vector<Thing> v;
    v.emplace_back();

    return 0;
}

int compiles(int argc, char ** argv)
{
    std::list<Thing> v;
    v.emplace_back();

    return 0;
}

这是编译器的错误。它是一个错误吗?

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:1752:31: error: call to deleted constructor of 'Thing'
            ::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
                              ^   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

... snip ...

note: 'Thing' has been explicitly marked deleted here
        Thing(const Thing &) = delete;

我真的不明白_Up(...)是如何导致复制构造函数被调用的。

4

2 回答 2

6

std::vector::emplace_back要求向量的类型与EmplaceConstructible一样MoveInsertable。由于您删除了复制构造函数并且没有自己定义移动构造函数,Thing因此不满足第二个要求。相反,std::list::emplace_back只需要列表类型为EmplaceConstructible.

于 2017-07-01T16:18:25.817 回答
5

当你有移动构造函数时它可以工作:

#include <vector>

class Thing {
public:
    Thing() {}
    Thing(const Thing &) = delete;
    Thing(Thing&&) = default;
};

int main() {
    std::vector<Thing> v;
    v.emplace_back();
    return 0;
}

的类型要求std::vector::emplace_back可以提供更多信息。

于 2017-07-01T16:19:06.010 回答