Все,станд :: unique_ptr удалена функция, initializer_list - приводится распределение
Когда я создаю экземпляр массива виджетов, используя формат инициализатор-лист, обнаженную указатель, который указывает на экземпляр виджета член-переменная компилируется, но после того, как изменения в std :: unique_ptr <> gcc дает ошибку компиляции относительно удаленной функции.
$ uname -a
Linux .. 3.5.0-21-родовой # 32-Ubuntu SMP Вт 11 декабря 18:51:59 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
$ г ++ - -версия
г ++ (Ubuntu/Linaro 4.7.2-5ubuntu1) 4.7.2
Этот код дает следующее сообщение об ошибке компилятора:
#include <stdlib.h>
#include <memory>
class Widget
{
public:
Widget() {}
};
class W1 : public Widget
{
public:
W1() {}
};
class W2 : public Widget
{
public:
W2() {}
};
class WFactory
{
public:
WFactory(const int i) : _w(new W1()) {}
WFactory(const char* s) : _w(new W2()) {}
~WFactory() { _w.reset(nullptr); }
// ~WFactory() { delete _w; } <--- for naked ptr
private:
// NOTE: does not compile
std::unique_ptr<Widget> _w;
// NOTE: does compile
// Widget* _w;
};
int main()
{
std::unique_ptr<Widget> a(new W1()); // <--- compiles fine
WFactory wf[] { 4, "msg" }; // <--- compiler error using unique_ptr<>
}
ошибка:
$ g++ -o unique_ptr -std=c++11 -Wall unique_ptr.cpp
unique_ptr.cpp: In function ‘int main()’:
unique_ptr.cpp:36:30: error: use of deleted function ‘WFactory::WFactory(const WFactory&)’
unique_ptr.cpp:22:7: note: ‘WFactory::WFactory(const WFactory&)’ is implicitly deleted because the default definition would be ill-formed:
unique_ptr.cpp:22:7: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = Widget; _Dp = std::default_delete<Widget>; std::unique_ptr<_Tp, _Dp> = std::unique_ptr<Widget>]’
In file included from /usr/include/c++/4.7/memory:86:0,
from unique_ptr.cpp:2:
/usr/include/c++/4.7/bits/unique_ptr.h:262:7: error: declared here
unique_ptr.cpp:36:30: error: use of deleted function ‘WFactory::WFactory(const WFactory&)’
unique_ptr.cpp:36:14: warning: unused variable ‘wf’ [-Wunused-variable]
Я в недоумении, либо: механика за кулисами, что дает удаленный fcxn; или более просто, почему выразительность std :: unique_ptr <> оказывается ограниченной по сравнению с голым ptr.
Мой вопрос:
- ошибка пилота?
- ошибка компилятора?
- Могу ли я заставить свой предназначенный код работать с некоторыми изменениями?
спасибо.
Edit 1
Исходя из ваших ответов, которые я ценю, я могу сделать следующее изменение WFactory:
(помечен как аморальный код)
class WFactory
{
public:
WFactory(const WFactory& wf)
{
(const_cast<WFactory&>(wf)).moveto(_w);
}
WFactory(const int i) : _w(new W1()) {}
WFactory(const char* s) : _w(new W2()) {}
~WFactory() { _w.reset(nullptr); }
void moveto(std::unique_ptr<Widget>& w)
{
w = std::move(_w);
}
private:
std::unique_ptr<Widget> _w;
};
и теперь программа компилируется и запускается. Я высоко ценю, что люди, отвечающие за стандарты, написали спецификацию по какой-либо причине, поэтому я публикую свой результат как добросовестную специализацию для моего дела, где я действительно хотел бы подчеркнуть уникальность ptr.
Edit 2
На основе ответов Джонатана, следующий код не подавляет неявное перемещение CTOR:
class WFactory
{
public:
WFactory(const int i) : _w(new W1()) {}
WFactory(const char* s) : _w(new W2()) {}
private:
std::unique_ptr<Widget> _w;
};
Обратите внимание, что нет никакого ~WFactory() {..}
вообще.
Возможно, есть ya-ans, но я обнаружил, что использование итерации C++ 11 в стиле wf [] в Main() возвращает ошибку no-copy-ctor-for-WFactory.То есть:
int Main()
..
WFactory wf[] { 4, "msg" };
for (WFactory iwf : wf) <---- compiler error again
// ..
for (unsigned i = 0; i < 2; ++i) <--- gcc happy
wf[i] // ..
}
Я предполагаю, что это само собой разумеется, что новый C++ 11-стиль итерация делает объект копию.
Инициализация через скошенные списки требует, к сожалению, объектов, подлежащих форматированию. –
Спасибо, это интересно. Где копия? Ошибка указывает, что WFactory должен быть скопирован. Я этого не понимаю. – JayInNyc
Это в спецификации языка. Копия фактически не будет на практике, но класс все равно должен иметь доступный конструктор копирования. –