2016-08-12 3 views
2
#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>()); 
} 

Если компиляции с г ++ 4.8.5, 5.2.0, 5.3.0 и -DDDDEQUE я получаю сообщение об ошибке многословного заканчивающегосяC++ станд :: Deque проблема конструктора копирования

.../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?

+2

Несвязанный, вам не хватает значения 'return' в вашем операторе присваивания. И fwiw, вы можете добавить clang 3.8 в список toolchains, который скомпилируется даже при определении 'DDDEQUE'. – WhozCraig

+0

Это больше похоже на вопрос о gcc. Поэтому, возможно, 'gcc' должен быть тегом. Btw, любая разница, если вы используете 'vd.emplace (vd.end(), 1, std :: move (std :: deque ())); вместо этого? – Walter

ответ

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, лязг компилирует все 4 (за исключением, возможно, d в зависимости от версии LIBC++ используется) и MSVC компилирует все 4 случая (используя свои собственные, связанные стандартную библиотеку, с libstdC++, лязг также не удается b и d).

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

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


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

От ссылки;

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

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

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

+1

"* Это изменилось в C++ 11, вы можете использовать уровень языка для поддержки функций поддержки *", move-constructor, 'emplace',' deleted', это все функции C++ 11 (= OP уже включен C++ 11) –

+0

@PiotrSkotnicki. Я это понимаю, но его код по-прежнему требует конструктора копирования и т. Д. – Niall

+0

вектор имеет такое же непринужденное требование, я прочитал вопрос как: «какая операция заставляет deque требовать копирования-конструктивности» –

Смежные вопросы