M
Mark
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.
Sample appreciated. Thanks in advance.
# include <map>
# include <boost/variant.hpp>
# include <boost/mpl/vector.hpp>
# include <boost/mpl/contains.hpp>
# include <boost/utility/enable_if.hpp>
# include <boost/lexical_cast.hpp>
# include <boost/variant.hpp>
# include <boost/any.hpp>
# include <boost/shared_ptr.hpp>
# include <vector>
# include <string>
# include <iostream>
// Generic visitor
template <typename Visitor, typename TypeList>
struct generic_visitor :
public boost::static_visitor<void>,
public Visitor
{
template <typename T>
inline void operator ()
( T& v, typename boost::enable_if<
typename boost::mpl::contains< TypeList, T >::type >::type *dummy= NULL )
{
Visitor:perator () (v);
}
template <typename T>
inline void operator ()
( T& v,
typename boost::disable_if <
typename boost::mpl::contains< TypeList, T >::type >::type *dummy = NULL )
{}
};
class nil {
protected :
nil(const nil& );
nil& operator = (const nil& ) ;
unsigned int abc ;
public :
unsigned int const get() { return abc ; }
nil ()
: abc ( 5 )
{}
};
template < typename Type >
class dispatch {
typedef boost::variant <
nil&, char&, int&, double&
private :
int test_int ;
double test_double ;
public :
dispatch ()
: test_int ( 1 )
, test_double ( 1. )
{}
template < typename T >
void doit ( T& in ) {
std::cout << "(typeid=" << typeid( in ).name() << std::endl;
typename dispatch< Type >::sql_field obj ( in );
boost::apply_visitor ( this->visitor, obj );
}
};
struct example_visitor
{
typedef generic_visitor
< example_visitor,
boost::mpl::vector<nil, char, int > > value_type;
typedef dispatch < example_visitor > dispatch_evisit ;
dispatch_evisit* ptr ;
int x ;
nil n ;
example_visitor()
: ptr ( 0 )
, x ( 4 )
{ std::cout << "." ; }
void operator () (char& v) {
std::cout << "character detected" << std::endl;
}
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_evisit ;
}
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() ;
}
std::cin.get();
}
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.
Sample appreciated. Thanks in advance.
# include <map>
# include <boost/variant.hpp>
# include <boost/mpl/vector.hpp>
# include <boost/mpl/contains.hpp>
# include <boost/utility/enable_if.hpp>
# include <boost/lexical_cast.hpp>
# include <boost/variant.hpp>
# include <boost/any.hpp>
# include <boost/shared_ptr.hpp>
# include <vector>
# include <string>
# include <iostream>
// Generic visitor
template <typename Visitor, typename TypeList>
struct generic_visitor :
public boost::static_visitor<void>,
public Visitor
{
template <typename T>
inline void operator ()
( T& v, typename boost::enable_if<
typename boost::mpl::contains< TypeList, T >::type >::type *dummy= NULL )
{
Visitor:perator () (v);
}
template <typename T>
inline void operator ()
( T& v,
typename boost::disable_if <
typename boost::mpl::contains< TypeList, T >::type >::type *dummy = NULL )
{}
};
class nil {
protected :
nil(const nil& );
nil& operator = (const nil& ) ;
unsigned int abc ;
public :
unsigned int const get() { return abc ; }
nil ()
: abc ( 5 )
{}
};
template < typename Type >
class dispatch {
typedef boost::variant <
nil&, char&, int&, double&
typename Type::value_type visitor ;sql_field;
private :
int test_int ;
double test_double ;
public :
dispatch ()
: test_int ( 1 )
, test_double ( 1. )
{}
template < typename T >
void doit ( T& in ) {
std::cout << "(typeid=" << typeid( in ).name() << std::endl;
typename dispatch< Type >::sql_field obj ( in );
boost::apply_visitor ( this->visitor, obj );
}
};
struct example_visitor
{
typedef generic_visitor
< example_visitor,
boost::mpl::vector<nil, char, int > > value_type;
typedef dispatch < example_visitor > dispatch_evisit ;
dispatch_evisit* ptr ;
int x ;
nil n ;
example_visitor()
: ptr ( 0 )
, x ( 4 )
{ std::cout << "." ; }
void operator () (char& v) {
std::cout << "character detected" << std::endl;
}
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_evisit ;
}
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() ;
}
std::cin.get();
}