Hi. I had the same question that is answered there, but the answer didn't fit my problem. I'm using scoped_ptr<node> inside node itself, so node is incomplete at the point of use. That forbids using auto_ptr, IIUC. I think it would be good to add to the answer: Q. Why doesn't scoped_ptr have a release() member? A. When reading source code, it is valuable to be able to draw conclusions about program behavior based on the types being used. If scoped_ptr had a release() member, it would become possible to transfer ownership of the held pointer, weakening its role as a way of limiting resource lifetime to a given context. Use std::auto_ptr where transfer of ownership is required, or shared_ptr if incomplete type support is needed. "or shared_ptr if incomplete type support is needed." is mine. How's that? Regards, Bruno
Bruno Martínez wrote:
Hi.
I had the same question that is answered there, but the answer didn't fit my problem. I'm using scoped_ptr<node> inside node itself, so node is incomplete at the point of use. That forbids using auto_ptr, IIUC.
You can use a scoped_ptr member with an incomplete type, as long as you include out of line default constructor (if you need one) and destructor.
On Wed, 23 Nov 2005 08:34:26 -0200, Peter Dimov
Bruno Martínez wrote:
Hi.
I had the same question that is answered there, but the answer didn't fit my problem. I'm using scoped_ptr<node> inside node itself, so node is incomplete at the point of use. That forbids using auto_ptr, IIUC.
You can use a scoped_ptr member with an incomplete type, as long as you include out of line default constructor (if you need one) and destructor.
I know. The problem is that I want incomplete types support *and* release
member function.
I don't seem to require a destructor in this case, for vc71 or gcc3.4:
#include
Bruno Martínez wrote:
On Wed, 23 Nov 2005 08:34:26 -0200, Peter Dimov
wrote: Bruno Martínez wrote:
Hi.
I had the same question that is answered there, but the answer didn't fit my problem. I'm using scoped_ptr<node> inside node itself, so node is incomplete at the point of use. That forbids using auto_ptr, IIUC.
You can use a scoped_ptr member with an incomplete type, as long as you include out of line default constructor (if you need one) and destructor.
I know. The problem is that I want incomplete types support *and* release member function.
Use std::auto_ptr and ensure that you obey Peter Dimov's recommendations. I know, that the standard says, in 5.3.5 "If the object being deleted has incomplete class type at the point of deletion and the complete class has a non-trivial destructor or a deallocation function, the behavior is undefined." and in 17.4.3.6 "if an incomplete type (3.9) is used as a template argument when instantiating a template component." There exists no special restriction on std::auto_ptr for incomplete classes and the main difference between std::auto_ptr and boost::scoped_ptr in this point is that the standard says, that "no diagnose is required", while boost will diagnose that due a safety belt in boost::checked_delete.
I don't seem to require a destructor in this case, for vc71 or gcc3.4:
#include
struct node { boost::scoped_ptr<node> next; };
int main() { node n; }
This snippet does not proof, that no d'tor is needed, because node::next is empty for the complete program run-time. Just assign a node to next, and you will see.... Greetings from Bremen, Daniel
On Thu, 24 Nov 2005 07:10:41 -0200, Daniel Krügler
Bruno Martínez wrote:
I know. The problem is that I want incomplete types support *and* release member function.
Use std::auto_ptr and ensure that you obey Peter Dimov's recommendations. I know, that the standard says, in 5.3.5
"If the object being deleted has incomplete class type at the point of deletion and the complete class has a non-trivial destructor or a deallocation function, the behavior is undefined."
and in 17.4.3.6
"if an incomplete type (3.9) is used as a template argument when instantiating a template component."
There exists no special restriction on std::auto_ptr for incomplete classes
I don't understand. There is a restriction. It's 17.4.3.6!
and the main difference between std::auto_ptr and boost::scoped_ptr in this point is that the standard says, that "no diagnose is required", while boost will diagnose that due a safety belt in boost::checked_delete.
Yes, scoped_ptr is very well the behaved.
I don't seem to require a destructor in this case, for vc71 or gcc3.4:
#include
struct node { boost::scoped_ptr<node> next; };
int main() { node n; }
This snippet does not proof, that no d'tor is needed, because node::next is empty for the complete program run-time. Just assign a node to next, and you will see...
I did, but it still works:
#include
Bruno Martínez wrote:
On Thu, 24 Nov 2005 07:10:41 -0200, Daniel Krügler
wrote: Bruno Martínez wrote:
I know. The problem is that I want incomplete types support *and* release member function.
Use std::auto_ptr and ensure that you obey Peter Dimov's recommendations. I know, that the standard says, in 5.3.5
"If the object being deleted has incomplete class type at the point of deletion and the complete class has a non-trivial destructor or a deallocation function, the behavior is undefined."
and in 17.4.3.6
"if an incomplete type (3.9) is used as a template argument when instantiating a template component."
There exists no special restriction on std::auto_ptr for incomplete classes
I don't understand. There is a restriction. It's 17.4.3.6!
OK, so you have to write your own auto_ptr or move_ptr. From a legal point of view, you can't use auto_ptr for incomplete classes, from a practical point of view you can do that provided that some rules concerning d'tor definition are obeyed.
I don't seem to require a destructor in this case, for vc71 or gcc3.4:
#include
struct node { boost::scoped_ptr<node> next; };
int main() { node n; }
This snippet does not proof, that no d'tor is needed, because node::next is empty for the complete program run-time. Just assign a node to next, and you will see...
I did, but it still works:
#include
struct node { boost::scoped_ptr<node> next; node(node* next = 0) : next(next) {} };
int main() { node n; n.next.reset(new node); }
I wasn't carefully reading your code, obviously ;-) It works, because at the point of the destructor of next the hosting class node is completely defined. You have a special case here, not the classical pimpl problem: struct A { struct Impl; boost::scoped_ptr<Impl> pimpl; }; because of your next member referencing the hosting class itself. In the A case pimpl's d'tor does not have the complete definition of Impl available, in contrast to your node class. Greetings, Daniel
On Mon, 28 Nov 2005 06:57:07 -0200, Daniel Krügler
Bruno Martínez wrote:
On Thu, 24 Nov 2005 07:10:41 -0200, Daniel Krügler
wrote: Bruno Martínez wrote:
I know. The problem is that I want incomplete types support *and* release member function.
Use std::auto_ptr and ensure that you obey Peter Dimov's recommendations. I know, that the standard says, in 5.3.5
"If the object being deleted has incomplete class type at the point of deletion and the complete class has a non-trivial destructor or a deallocation function, the behavior is undefined."
and in 17.4.3.6
"if an incomplete type (3.9) is used as a template argument when instantiating a template component."
There exists no special restriction on std::auto_ptr for incomplete classes
I don't understand. There is a restriction. It's 17.4.3.6!
OK, so you have to write your own auto_ptr or move_ptr.
From a legal point of view, you can't use auto_ptr for incomplete classes, from a practical point of view you can do that provided that some rules concerning d'tor definition are obeyed.
Yes, that's it. This conclusion is the one I think should be added to the FAQ.
#include
struct node { boost::scoped_ptr<node> next; node(node* next = 0) : next(next) {} };
int main() { node n; n.next.reset(new node); }
I wasn't carefully reading your code, obviously ;-) It works, because at the point of the destructor of next the hosting class node is completely defined. You have a special case here, not the classical pimpl problem:
struct A { struct Impl; boost::scoped_ptr<Impl> pimpl; };
because of your next member referencing the hosting class itself. In the A case pimpl's d'tor does not have the complete definition of Impl available, in contrast to your node class.
Yes, it's not exactly the same. Bruno
participants (3)
-
Bruno Martínez
-
Daniel Krügler
-
Peter Dimov