|
Boost Users : |
Subject: Re: [Boost-users] [Container] Forward declaration of movable types
From: Ion Gaztañaga (igaztanaga_at_[hidden])
Date: 2011-08-17 05:50:15
El 16/08/2011 19:05, Szymon Gatner escribió:
> So there is no really a way around it, is there? Either:
>
> 1) objects in container have to be kept by pointer to break dependency
> but then they
> have to be allocated on the heap so there is little or no benefit in
> making them movable
> (as smart pointer will provide necessary copy/move/ownership semantics)
>
> 2) whole container has to be pimpled so that hidden implementation may then take
> advantage of all move goodies like container emplacing
>
> I feel like 2nd option is the one that gives real benefits. Is that right?
Right.
>
> Also, I often write code like:
>
> class Widget
> {
> public:
> typedef std::vector<shared_ptr<MyMovable> > MyMovables;
>
> const MyMovables& movables() const;
>
> private:
>
> MyMovables movables_;
> }
>
> so that clients can later do:
>
> BOOST_FOREACH(MyMovable& m, indirect(widget->movables())
> {
> // do something with m
> }
>
> how to design Widget's class API in similar way if MyMovables is
> hidden behind pimpl?
//hpp
class MyMovable;
class Widget
{
public:
typedef std::vector<MyMovable> MyMovables;
const MyMovables& movables() const;
private:
class Internals;
Internals *impl_;
};
//cpp
#include "MyMovable.hpp"
const Widget::MyMovables& Widget::movables() const
{
return impl_->movables_;
}
> PS. I just compiled such a code:
>
> //widget.hpp
>
> class Movable; // only forward declared
>
> class Widget
> {
> boost::container::vector<Movable> movables_;
> }
>
> and widget.cpp properly adds Movable instances by moving them to movable_.
>
> Why does this work? If this is normal then I have no problem at all ;)
Because you haven't instantiated the type. This does not compile:
#include<boost/container/vector.hpp>
class Movable; // only forward declared
class Widget
{
boost::container::vector<Movable> movables_;
};
int main()
{
Widget w;
}
However, I just checked that if you put all the functions in a cpp it
will work fine. I think you've discovered a great Boost.Container
feature derived from the care I put to support recursive types and avoid
too early Movable instantiations:
//hpp
#include<boost/container/vector.hpp>
class Movable; // only forward declared
class Widget
{
boost::container::vector<Movable> movables_;
public:
Widget(const Widget &);
Widget &operator= (const Widget &);
Widget();
~Widget();
};
//cpp
//here implement constructor/destructor/assignment...
The difference with pimpl is that you need to include "vector.hpp", with
pimpl, you don't need to.
Best,
Ion
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net