Boost logo

Boost :

Subject: Re: [boost] Formal Review Request: TypeErasure
From: Thomas Petit (thomas.petit33_at_[hidden])
Date: 2012-05-30 04:30:42


2012/5/22 Steven Watanabe <watanabesj_at_[hidden]>

> [snip]
>
>
This look promising !
If I understand well, your library could greatly help to achieve value
semantics and concepts-based polymorphism
as described by Sean Parent here :
http://cppnow.org/session/value-semantics-and-concepts-based-polymorphism/,
right?

If so, I would like to see a simpler "polymorphic range formatter" example,
because the current one is the first and only example who deal with
inheritance
and virtual functions, but it is so complicated that it lost me.

To be clear, if I have the following code using traditional OO style with
runtime polymorphism :
(Note that I dropped every functions template to avoid complications for
now)
---------------------

#include <iostream>
#include <vector>

class abstract_printer {
public:
    void print(std::ostream& os, const std::vector<int>& v) const {
        do_print(os, v);
    }
    virtual ~abstract_printer() {}
protected:
    virtual void do_print(std::ostream& os, const std::vector<int>&
elements) const = 0;
};

class separator_printer : public abstract_printer {
public:
    explicit separator_printer(const std::string& sep) : separator(sep) {}
protected:
    virtual void do_print(std::ostream& os, const std::vector<int>& v)
const {
        for(int i : v){
            os << separator.c_str() << i;
        }
    }
private:
    std::string separator;
};

class column_separator_printer : public abstract_printer {
public:
    column_separator_printer(const std::string& sep, std::size_t
num_columns)
      : separator(sep),
        cols(num_columns)
    {}
protected:
    virtual void do_print(std::ostream& os, const std::vector<int>& v)
const {
        std::size_t count = 0;
        for(int i : v){
            os << i;
            int temp = i;
            ++temp;
            os << separator.c_str();
            if(++count % cols == 0) {
                os << "\n";
            }
        }
    }
private:
    std::string separator;
    std::size_t cols;
};
-------------

As noted in you documentation, runtime polymorphism almost every time
requires dynamic memory management,
so we are stuck and forced to use those classes pretty much like this:

-------------
abstract_printer* p1 = new separator_printer(",");
abstract_printer* p2 = new column_separator_printer(",", 4);

std::vector<abstract_printer*> printers;
printers.push_back(p1);
printers.push_back(p2);

for(abstract_printer* printer : printers)
{
    printer->print(std::cout, test);
    std::cout << std::endl;
}

for(abstract_printer* printer : printers)
{
    delete printer;
}

-------------

Now what are the minimal, non-intrusive modifications using Boost.TypeErase
we have to make so we can write in a value-based style, with regular types ?
Can we achieve something like this ? :

--------------
std::vector<any<printable>> printers;
printers.push_back(separator_printer(","));
printers.push_back(column_separator_printer(",", 4));
for(any<printable>& printer : printers)
{
    printer->print(std::cout, test);
}
-------------

Thanks.
Thomas.


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