C++ std::deque copy конструктор проблема

#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 ответ

Похоже, это относится к 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 также завершается ошибкой b а также d).

Есть ли deque (но нет vector) нужен конструктор копирования для gcc?

Похоже, да, gcc по-прежнему требует конструктор копирования.


В более формальных терминах; в C++03 std::deque требуется, чтобы тип, используемый в контейнере, был копируемым и копируемым. Это изменилось в C++11, требования были смягчены, хотя полный тип, как правило, все еще требуется - учитывая образец OP, ваша стандартная библиотека по-прежнему требует создания и назначения копии.

Из ссылки по ссылке;

T - тип элементов.

T должен соответствовать требованиям Copy Assignable и CopyConstructible. (до C++11)

Требования, предъявляемые к элементам, зависят от фактических операций, выполняемых над контейнером. Как правило, требуется, чтобы тип элемента был полным типом и удовлетворял требованиям Erasable, но многие функции-члены предъявляют более строгие требования. (начиная с C++11)

Другие вопросы по тегам