2015-11-10 3 views
2

Почему это не компилируется? (Требуется копия-конструктор для станд :: unique_ptr <>) Почему std :: vector нецелевых объектов не инициализируется с помощью initializer_list?

std::vector<std::unique_ptr<int>> vec{std:unique_ptr<int>(new int)}; 

Созданный указатель является г-значение, так почему она не может быть перемещен в вектор?

Есть ли такой же короткий способ инициализации вектора, который работает?

+4

'std :: initializer_list' является сломанным для типов только для перемещения. Есть несколько предложений, чтобы исправить это, например [этот] (http://open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4166.pdf). – TartanLlama

+0

Действительно на 2011 год, а не 2014 год? 'std :: make_unique' доступен с C++ 14, а не C++ 11; согласно Herb Sutter, оставив это «частично надзором» в процессе стандартизации 2011 года; это предсказуемо, что кто-то будет изучать стандарт для этого, и тогда он должен быть правильным стандартом. –

+0

@decltype_auto: я удалил использование std :: make_unique() вместо изменения тега, потому что основная проблема вопроса существует в C++ 11 – Knitschi

ответ

0

Простая проблема заключается в том, что std::unique_ptr «s копирования является deleted т е р, но construct из std::, который найден вызывает ::new, который инициирует вызов этой удаленной копией CTOR.

LibC++/лязг ++ - 3,5

/USR/включать/C++/v1/память: 1645: 31: ошибка: вызов неявно удаленные копии конструктор 'станд :: __ 1 :: unique_ptr>'

template <class _Up, class... _Args> 
_LIBCPP_INLINE_VISIBILITY 
void 
construct(_Up* __p, _Args&&... __args) 
{ 
    ::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...); 
} 

libstdC++/г ++ - 4,9

/usr/include/c++/4.9/bits/stl_construct.h:75:7: error: use of deleted function 
‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) 
[with _Tp = int; _Dp = std::default_delete<int>]’ 
     { ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); } 

Это несколько заманчиво попытаться сформулировать пользовательскую перегрузку std::allocator как использовать его для типа распределителя контейнера.

Для тех, кто не может противостоять этому искушению (как я)

Чтобы сделать пользовательский аллокатора по крайней мере используется компилятором он по крайней мере, нуждается в этой минимальной численности населения.

template<typename T> 
struct allocator : public std::allocator<T> { 
    using Base = std::allocator<T>; 
    using Base::Base; 

    template<typename U> 
    struct rebind {typedef allocator<U> other;}; 

    template<typename Up, typename... Args> 
    void construct(Up* p, Args&&... args); 
}; 

Это вряд ли полный пока (не говоря уже бы я construct правильно повторно реализован еще), но, по крайней мере, это вызывает ошибку вверх от бездн Lib в дневное время пользовательских исходный файл.

+0

Я не совсем понимаю, к чему вы клоните. Будет ли использовать ваш распределитель, чтобы линия кода работала? – Knitschi

+0

@ Knitschi: по крайней мере, это та цель, но это анзац. Btw, что 'Args && ... args' в прослушанной' construct'call вычисляет const std :: unique_ptr &. –

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