简体   繁体   English

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

[英]C++ std::deque copy constructor issue

#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>());
}

If compiling with g++ 4.8.5, 5.2.0, 5.3.0 and -DDDDEQUE I get a verbose error message ending with 如果使用g ++ -DDDDEQUE-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;

without -D... compiles OK. 没有-D...编译就可以了。 With VC2015, VC2012 both versions compile OK. 使用VC2015,VC2012两个版本都可以编译。 Does deque (but not vector ) need the copy constructor for gcc? deque (但不是vector )是否需要gcc的副本构造函数?

This appears to be specific to libstdc++ (gcc); 这似乎特定于libstdc ++(gcc); given the code below; 给出以下代码;

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++ fails to compile b , and d , clang compiles all 4 (except possibly d depending on the version of libc++ used) and MSVC compiles all 4 cases (using their own associated standard library; with libstdc++, clang also fails b and d ). G ++无法编译bd ,clang编译所有4种情况(可能是d具体取决于所使用的libc ++版本),MSVC编译所有4种情况(使用它们自己的关联标准库;对于libstdc ++,clang也会失败bd )。

Does deque (but not vector ) need the copy constructor for gcc? deque (但不是vector )是否需要gcc的副本构造函数?

It appears as though, yes gcc does still require the copy constructor. 看来,是的,gcc仍然需要复制构造函数。


In more formal terms; 用更正式的说法; in C++03 std::deque required the type used in the container to be Copy Constructible and Copy Assignable . 在C ++ 03中, std::deque要求容器中使用的类型为Copy ConstructableCopy Assignable This changed in C++11, the requirements were relaxed, albeit a complete type is generally still required - given the OP sample, your standard library still requires the copy construction and assignment. 在C ++ 11中对此进行了更改,放宽了要求,尽管通常仍需要完整类型-给定OP示例,您的标准库仍然需要复制构造和赋值。

From the linked reference; 从链接的参考;

T - The type of the elements. T元素的类型。

T must meet the requirements of CopyAssignable and CopyConstructible . T必须满足CopyAssignableCopyConstructible的要求。 (until C++11) (直到C ++ 11)

The requirements that are imposed on the elements depend on the actual operations performed on the container. 对元素施加的要求取决于对容器执行的实际操作。 Generally, it is required that element type is a complete type and meets the requirements of Erasable , but many member functions impose stricter requirements. 通常,要求元素类型是完整类型并满足Erasable的要求,但是许多成员函数提出了更严格的要求。 (since C++11) (自C ++ 11起)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM