Re: [boost] STL containers and incomplete types

Am Freitag 16 Mai 2008 21:32:56 schrieb Maik Beckmann:
Hello,
Does boost got something to do this struct node { std::vector<node> children; // node is incomplete }; in a way which conform with the standard which disallows STL containers of incomplete types?
thx, -- Maik
This issue strikes boost.property_tree <boost/ptree.hpp> ... template<class C, class K, class P, class D, class X> class basic_ptree { ... typedef basic_ptree<C, K, P, D, X> self_type; ... typedef std::pair<key_type, self_type> value_type; // ..self_type is incomplete! ... typedef std::list<value_type> container_type; ... container_type m_container; <boost/ptree.hpp> -- Maik PS: I had to apply this <link> http://article.gmane.org/gmane.comp.lib.boost.devel/164866/match=property%5f... </link> to get libs/property_tree/test/sandbox.cpp compiled.

Hi! Maik Beckmann schrieb:
Am Freitag 16 Mai 2008 21:32:56 schrieb Maik Beckmann:
Hello,
Does boost got something to do this struct node { std::vector<node> children; // node is incomplete }; in a way which conform with the standard which disallows STL containers of incomplete types?
Using boost::shared_ptr or boost pointer containers come to mind ( http://www.boost.org/doc/libs/1_35_0/libs/ptr_container/doc/ptr_container.ht... ). But I don't know weather pointer containers allow incomplete types. I couldn't find it in the documentation. Frank

On May 18, 2008, at 1:29 PM, Frank Birbacher wrote:
Hi!
Maik Beckmann schrieb:
Am Freitag 16 Mai 2008 21:32:56 schrieb Maik Beckmann:
Hello,
Does boost got something to do this struct node { std::vector<node> children; // node is incomplete }; in a way which conform with the standard which disallows STL containers of incomplete types?
Using boost::shared_ptr or boost pointer containers come to mind ( http://www.boost.org/doc/libs/1_35_0/libs/ptr_container/doc/ptr_container.ht... ). But I don't know weather pointer containers allow incomplete types. I couldn't find it in the documentation.
Maybe recursive_wrapper could help? http://www.boost.org/doc/libs/1_35_0/doc/html/boost/recursive_wrapper.html HTH, Giuseppe

Am Sonntag 18 Mai 2008 14:08:16 schrieb Giuseppe Ottaviano:
On May 18, 2008, at 1:29 PM, Frank Birbacher wrote:
Hi!
Maik Beckmann schrieb:
Am Freitag 16 Mai 2008 21:32:56 schrieb Maik Beckmann:
Hello,
Does boost got something to do this struct node { std::vector<node> children; // node is incomplete }; in a way which conform with the standard which disallows STL containers of incomplete types?
Using boost::shared_ptr or boost pointer containers come to mind ( http://www.boost.org/doc/libs/1_35_0/libs/ptr_container/doc/ptr_container .html ). But I don't know weather pointer containers allow incomplete types. I couldn't find it in the documentation.
According to this example http://www.boost.org/doc/libs/1_35_0/libs/ptr_container/test/tree_test.cpp they do.
Maybe recursive_wrapper could help? http://www.boost.org/doc/libs/1_35_0/doc/html/boost/recursive_wrapper.html
It works, but its allways used in a boost.variant context, according to a quick grep at the boost root dir. Aside both solutions might do the trick I'm curious about what a boost/c++ guru would write into a STL-FAQ as a solution, since this problem isn't new. A possible answer might be: As matter of fact all common STL implementations have a vector/list class which works with incomplete types. Other container most likely won't do the job. Thanks, -- Maik

On Sun, May 18, 2008 at 3:52 PM, Maik Beckmann <beckmann.maik@googlemail.com> wrote:
Am Sonntag 18 Mai 2008 14:08:16 schrieb Giuseppe Ottaviano:
On May 18, 2008, at 1:29 PM, Frank Birbacher wrote:
Hi!
Maik Beckmann schrieb:
Am Freitag 16 Mai 2008 21:32:56 schrieb Maik Beckmann:
Hello,
Does boost got something to do this struct node { std::vector<node> children; // node is incomplete }; in a way which conform with the standard which disallows STL containers of incomplete types?
Using boost::shared_ptr or boost pointer containers come to mind ( http://www.boost.org/doc/libs/1_35_0/libs/ptr_container/doc/ptr_container .html ). But I don't know weather pointer containers allow incomplete types. I couldn't find it in the documentation.
Aside both solutions might do the trick I'm curious about what a boost/c++ guru would write into a STL-FAQ as a solution, since this problem isn't new.
I'm not a guru, but Instead of a vector<shared_ptrs<T> >, I'have used a shared_ptr <vector<T> > to implement recursive data structures. A clone pointer would work even better.
A possible answer might be: As matter of fact all common STL implementations have a vector/list class which works with incomplete types.
Not necessarily in debug builds. HTH, -- gpd

Am Sonntag 18 Mai 2008 19:28:42 schrieb Giovanni Piero Deretta:
On Sun, May 18, 2008 at 3:52 PM, Maik Beckmann I'm not a guru, but Instead of a vector<shared_ptrs<T> >, I'have used a shared_ptr <vector<T> > to implement recursive data structures. A clone pointer would work even better.
Giovanni, very nice! At the c.l.c.m Jan posted another solution () <code> struct tree_node { std::vector<tree_node> & children; tree_node() : children(*new std::vector<tree_node>) { } tree_node(const tree_node & n) : children(*new std::vector<tree_node> (n.children)) { } tree_node & operator =(tree_node n) { this->swap(n); return *this; } ~tree_node() { delete &this->children; } void swap(tree_node & n) { this->children.swap(n.children); } }; </code> which doesn't involve boost. Both use the fact new std::vector<incomplete_type> solves the problem. Thank you very much, -- Maik PS: boost.poperty_tree should be fixed

Ah, this works too, for the same reason: struct node { boost::recursive_wrapper<std::vector<node> > children; }; and is my personal favorite. -- Maik

Am Montag 19 Mai 2008 01:36:08 schrieb Maik Beckmann:
At the c.l.c.m Jan posted another solution ()
This should have been: At the c.l.c.m Jan posted another solution (http://tinyurl.com/5ojbyc) ... Sorry, -- Maik

Am Sonntag 18 Mai 2008 19:28:42 schrieb Giovanni Piero Deretta:
On Sun, May 18, 2008 at 3:52 PM, Maik Beckmann I'm not a guru, but Instead of a vector<shared_ptrs<T> >, I'have used a shared_ptr <vector<T> > to implement recursive data structures. A clone pointer would work even better.
Giovanni, very nice!
A standard conforming compiler is allowed to reject std::vector<T> for incomplete T. Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

Am Montag 19 Mai 2008 08:02:50 schrieb Emil Dotchevski:
Am Sonntag 18 Mai 2008 19:28:42 schrieb Giovanni Piero Deretta:
On Sun, May 18, 2008 at 3:52 PM, Maik Beckmann I'm not a guru, but Instead of a vector<shared_ptrs<T> >, I'have used a shared_ptr <vector<T> > to implement recursive data structures. A clone pointer would work even better.
Giovanni, very nice!
A standard conforming compiler is allowed to reject std::vector<T> for incomplete T.
But in this specific recursive case T is self_type and thus complete when it comes to new vector<self_type>, right?

On Mon, May 19, 2008 at 8:02 AM, Emil Dotchevski <emil@revergestudios.com> wrote:
Am Sonntag 18 Mai 2008 19:28:42 schrieb Giovanni Piero Deretta:
On Sun, May 18, 2008 at 3:52 PM, Maik Beckmann I'm not a guru, but Instead of a vector<shared_ptrs<T> >, I'have used a shared_ptr <vector<T> > to implement recursive data structures. A clone pointer would work even better.
Giovanni, very nice!
A standard conforming compiler is allowed to reject std::vector<T> for incomplete T.
Are you sure about it? I think that the standard says (I do not have it, I'm looking at the last draft): "In particular, the effects are undefined in the following cases: if an incomplete type is used as a template argument when instantiating a template component." I'm not a language lawyer, but does boost::shared_ptr<vector<T> > count as an instantiation? The definition of (implicit) template instantiation in the draft I have (14.7.1) says: "Unless a class template specialization has been explicitly instantiated (14.7.2) or explicitly specialized (14.7.3), the class template specialization is implicitly instantiated when the specialization is referenced in a context that requires a completely-deļ¬ned object type or when the completeness of the class type affects the semantics of the program. " In particular the example in this section shows that creating a pointer to a template specialization does not require an instantiation. Boost shared_ptr explicitly allows its parameter to be incomplete, so it will definitely not be used in a context that requires a completely defined object. The boost::shared_ptr constructor is another story of course. -- gpd

Frank Birbacher skrev:
Hi!
Maik Beckmann schrieb:
Am Freitag 16 Mai 2008 21:32:56 schrieb Maik Beckmann:
Hello,
Does boost got something to do this struct node { std::vector<node> children; // node is incomplete }; in a way which conform with the standard which disallows STL containers of incomplete types?
Using boost::shared_ptr or boost pointer containers come to mind ( http://www.boost.org/doc/libs/1_35_0/libs/ptr_container/doc/ptr_container.ht... ). But I don't know weather pointer containers allow incomplete types. I couldn't find it in the documentation.
That should work just fine. Isn't there a FAQ entry about this? best regards -Thorsten
participants (6)
-
Emil Dotchevski
-
Frank Birbacher
-
Giovanni Piero Deretta
-
Giuseppe Ottaviano
-
Maik Beckmann
-
Thorsten Ottosen