Tutti,std :: unique_ptr cancellato funzione, initializer_list - guidato allocazione
Quando un'istanza di un array di widget utilizzando un formato di inizializzazione-list, un puntatore nuda che punta a un'istanza widget di membro variabile compila, ma dopo il cambio di std :: unique_ptr <> gcc restituisce un errore di compilazione relativo a una funzione cancellata.
$ uname -a
Linux .. 3.5.0-21-generiC# 32-Ubuntu SMP martedì 11 dicembre 18:51:59 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
$ g ++ - -version
g ++ (Ubuntu/Linaro 4.7.2-5ubuntu1) 4.7.2
Questo codice dà il seguente errore del compilatore:
#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<>
}
errore:
$ 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]
Sono ad una perdita quanto a uno: la meccanica dietro le quinte che produce un fcxn soppressa; o più semplicemente, perché l'espressività di std :: unique_ptr <> sembra limitata rispetto a un ptr nudo.
La mia domanda è: Errore
- pilota?
- errore del compilatore?
- posso ottenere il codice previsto per funzionare con qualche modifica?
Grazie.
Modifica 1
In base alle vostre risposte, che apprezzo, posso fare la seguente modifica al WFactory:
(contrassegnato codice come immorale)
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;
};
e ora il programma viene compilato e eseguito. Apprezzo che gli standard abbiano scritto le specifiche per un motivo, quindi pubblico il mio risultato come una specializzazione in buona fede per il mio caso, dove vorrei davvero sottolineare l'unicità del ptr.
Edit 2
Sulla base di risposte di Jonathan, il seguente codice non sopprime l'implicito mossa ctor:
class WFactory
{
public:
WFactory(const int i) : _w(new W1()) {}
WFactory(const char* s) : _w(new W2()) {}
private:
std::unique_ptr<Widget> _w;
};
Si noti che non v'è alcun ~WFactory() {..}
a tutti.
Forse c'è ya-ans, ma ho scoperto che l'utilizzo di un'iterazione in stile C++ 11 su wf [] in Main() riporta l'errore no-copy-ctor-for-WFactory.Cioè:
int Main()
..
WFactory wf[] { 4, "msg" };
for (WFactory iwf : wf) <---- compiler error again
// ..
for (unsigned i = 0; i < 2; ++i) <--- gcc happy
wf[i] // ..
}
Credo che sia evidente che la nuova iterazione C++ 11-stile sta facendo una copia dell'oggetto.
L'inizializzazione tramite elenchi rinforzati richiede che gli oggetti siano formalmente copiabili, sfortunatamente. –
Grazie, è interessante. Dov'è la copia? L'errore indica che WFactory deve essere copiabile. Non capisco. – JayInNyc
È nelle specifiche della lingua. La copia in realtà non si verificherà nella pratica, ma la classe deve ancora avere un costruttore di copia accessibile. –