C ++ std :: deque复制构造函数问题

时间:2016-08-12 07:30:58

标签: c++ c++11 copy-constructor move-semantics deque

#include <deque>
#include <vector>

struct A
{
    A(int* const p) : m_P(p) {}
    A(A&& rhs)      : m_P(rhs.m_P) { rhs.m_P = nullptr; }
    A& operator=(A&& rhs) { delete m_P; m_P = rhs.m_P; rhs.m_P = nullptr; }
    ~A() { delete m_P; }

    A(A const& rhs)            = delete;
    A& operator=(A const& rhs) = delete;

    int* m_P;
};

int main()
{
#ifdef DDDEQUE
    std::vector<std::pair<int, std::deque<A> > >  vd;
    vd.emplace(vd.end(), 1, std::deque<A>());
#endif // #ifdef DDDEQUE

    std::vector<std::pair<int, std::vector<A> > > vv;
    vv.emplace(vv.end(), 1, std::vector<A>());
}

如果使用g ++ 4.8.5,5.2.0,5.3.0和-DDDDEQUE进行编译,我会收到以

结尾的详细错误消息
.../bits/stl_construct.h:75:7: error: use of deleted function ‘A::A(const A&)’
     { ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
       ^
gcc.cpp:11:5: note: declared here
      A(A const& rhs)            = delete;

没有-D...编译好。 使用VC2015,VC2012两个版本都可以编译好。 deque(但不是vector)是否需要gcc的复制构造函数?

1 个答案:

答案 0 :(得分:3)

这似乎是libstdc ++(gcc)特有的;给出以下代码;

struct A
{
    A() {};
    A(A&&) noexcept { }
    A& operator=(A&&) noexcept  { return *this; }
    ~A() { }
};

int main()
{
    std::vector<A> a;
    a.push_back(A{}); // or emplace(a.end()... etc.
    std::vector<std::deque<A>> b;
    b.push_back(std::deque<A>());
    std::vector<std::pair<int,A>> c;
    c.push_back(std::pair<int,A>{});
    std::vector<std::pair<int,std::deque<A>>> d;
    d.push_back(std::pair<int,std::deque<A>>{});
}

G ++无法编译b,而d,clang编译所有4个(可能d除外,具体取决于所使用的libc ++版本),MSVC编译所有4个案例(使用自己的关联的标准库;使用libstdc ++,clang也失败了bd)。

  

deque(但不是vector)是否需要gcc的复制构造函数?

好像是,gcc仍然需要复制构造函数。

以更正式的方式;在C ++ 03 std::deque中,要求容器中使用的类型为 Copy Constructible Copy Assignable 。这在C ++ 11中有所改变,要求很宽松,尽管通常仍然需要完整的类型 - 考虑到OP样本,您的标准库仍然需要复制构造和分配。

来自链接参考;

  

T - 元素的类型。

     

T必须符合 CopyAssignable CopyConstructible 的要求。 (直到C ++ 11)

     

对元素施加的要求取决于对容器执行的实际操作。通常,要求元素类型是完整类型并满足 Erasable 的要求,但许多成员函数强加了更严格的要求。 (自C ++ 11起)