Re: Eliminate second invocation of class (example_visitor) object
On 2013-06-29, Mark <ma740988@gmail.com> wrote:
Code referenced below compiles and runs. The issue I'm faced with is
the constructor for example_visitor is invoked twice. The second
invocation of the example_visitor constructor is predicated on
invocation of dispatch in particular the line: typename
Type::value_type visitor ; within dispatch
What modifications needs to occur such that I could use the 'this'
pointer from the first instance of example_visitor in dispatch?
I tried modifying the code to have example_visitor derive off
dispatch but to no avail.
Instead of letting generic_visitor derive from Visitor,
let it contain a pointer to its Visitor; you'll need to
add a extra constructor for dispatch and generic_visitor
in order to initialize this pointer.
Sample appreciated.
# include <boost/variant.hpp>
# include <boost/mpl/vector.hpp>
# include <boost/mpl/contains.hpp>
# include <boost/utility/enable_if.hpp>
# include <iostream>
template <typename Visitor, typename TypeList>
struct generic_visitor :
public boost::static_visitor<void>
{
Visitor *myvisitor;
generic_visitor(Visitor *v) : myvisitor(v) {}
template <typename T>
inline void operator()
( T& v, typename boost::enable_if<
typename boost::mpl::contains<TypeList, T>::type>::type* = NULL)
{
(*myvisitor)(v);
}
template <typename T>
inline void operator() (T&,
typename boost::disable_if<
typename boost::mpl::contains<TypeList, T>::type>::type* = NULL)
{}
};
class nil {
private :
unsigned int abc;
public :
unsigned int get() {return abc;}
nil() : abc(5) {}
};
template <typename Type>
class dispatch
{
generic_visitor<Type, boost::mpl::vector<nil, char, int> > visitor;
public :
dispatch(Type *v) : visitor(v) {}
template < typename T >
void doit ( T& in ) {
std::cout << "(typeid=" << typeid(in).name() << std::endl;
boost::variant<nil&, char&, int&, double&> obj = in;
boost::apply_visitor(visitor, obj);
}
};
struct example_visitor
{
dispatch<example_visitor> *ptr;
int x;
nil n;
example_visitor() : ptr(0), x(4)
{
std::cout << "[example_visitor:ctor]";
}
void operator()(char&) {
std::cout << "character detected\n";
}
void operator()(int& v) {
std::cout << "integer detected=" << v << std::endl;
}
void operator()(nil& v) {
std::cout << "nil detected=" << v.get() << std::endl;
}
void initialize()
{
ptr = new dispatch<example_visitor>(this);
}
void execute()
{
if (ptr) {
ptr->doit(x);
ptr->doit(n);
x += 2;
}
}
};
int main()
{
example_visitor test;
test.initialize();
for (unsigned int odx = 0; odx != 10; ++odx) {
test.execute();
}
}