Boost logo

Boost :

From: Steven Kirk (steven.kirk_at_[hidden])
Date: 2001-03-20 04:08:46


Thanks for checking this out for me Jeremy, but I think in my case there's a
simpler solution. What I'm doing is creating a new container class, but if I
forward declare the abstract class, define the container class and *then*
define the abstract class, everything seems to compile ok. Here's what I
mean:

--
#include <boost/iterator_adaptors.hpp>
#include <map>
class Abstract;
class AbstractContainer {
private:
    typedef std::map<int, Abstract*> Container;
    struct Select {
        typedef Container::mapped_type result_type;
        Abstract &operator()(const Container::value_type &r) const
            { return *r.second; }
    };
    typedef boost::projection_iterator_pair_generator<Select,
        Container::iterator, Container::const_iterator> IteratorGen;
    Container c;
    typedef IteratorGen::iterator DummyToWorkAroundBccBug;
public:
    typedef IteratorGen::iterator iterator;
    typedef IteratorGen::const_iterator const_iterator;
    iterator begin()                            { return
iterator(c.begin()); }
    iterator end()                              { return
iterator(c.end()); }
    const_iterator begin() const
    {
        // Bcc gets an internal compiler error if we try to create a
        // const_iterator directly.
        return boost::make_projection_iterator<Select>(c.begin());
    }
    const_iterator end() const
    {
        // Bcc gets an internal compiler error if we try to create a
        // const_iterator directly.
        return boost::make_projection_iterator<Select>(c.end());
    }
};
class Abstract {
public:
    virtual void example() = 0;
    int data;
};
int main(int argc, char* argv[])
{
    AbstractContainer ac;
    return 0;
}
--
There are a number of workarounds in the code to deal with problems with
Bcc, but the code appears to work. Can you see any potential problems with
this? I would prefer to do it this way rather than using "bogus" types in
the iterator - it just seems a little neater.
Thanks again,
Steven.
> Hi Steven,
>
> Upon closer inspection, I don't think there's a way to get projection
> iterator to handle a value_type that is an abstract base class. However,
> there is a workaround. Instead of using the projection_iterator_generator,
> you can directly use iterator_adaptor. You will need to specify a "bogus"
> (but harmless) type for the value_type of the iterator. This is harmless
> because, even if you did use Abstract as the value_type, any algorithm
> using that type (and not the pointer or reference to it instead) would run
> into problems.
>
> boost::iterator_adaptor<AbstractMap::iterator,
>   boost::projection_iterator_policies<GetReference>,
>   char, // dummy value_type
>   Abstract&, Abstract*, std::input_iterator_tag>
>
> I had to roll back the changes I had made to named_template_params.hpp,
> so you'll need to update again.
>
> Ciao,
> Jeremy

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk