-
February 17th, 2013, 03:51 PM
#1
Dependent type - boost::apply_visitor
Consider,
Code:
# include <iostream>
# include <map>
# include <boost/variant.hpp>
# include <boost/mpl/vector.hpp>
# include <boost/mpl/contains.hpp>
# include <boost/bind.hpp>
# include <boost/utility/enable_if.hpp>
// Generic visitor that does magical dispatching of
// types and delegates passes down to your visitor only
// those types specified in a type list.
template <typename Visitor, typename TypeList>
struct lets_see :
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 ) const
{
Visitor::operator () (v);
}
template <typename T>
inline void operator ()
( T v,
typename boost::disable_if <
typename boost::mpl::contains< TypeList, T >::type >::type *dummy = NULL ) const
{}
};
struct nil { int x ; };
struct example_visitor
{
typedef lets_see
< example_visitor,
boost::mpl::vector<nil, char, int > > value_type;
inline void operator () (char v) const {
std::cout << "character detected" << std::endl;
}
inline void operator () (int v) const {
std::cout << "integer detected=" << v << std::endl;
}
inline void operator () (nil v) const {
std::cout << "nil detected=" << v.x << std::endl;
}
};
template < typename T >
class Foo {
protected :
typedef boost::variant <
nil, char, int, double
> sql_field;
T visitor ;
typedef std::map< unsigned int , Foo <T>* > FooMap;
static FooMap mFooMap;
public :
static Foo <T>* createInstance( unsigned int const );
void Register( unsigned int const, Foo< T >* );
virtual void doWork () ;
};
template < typename T>
typename Foo<T>::FooMap Foo<T>::mFooMap;
template < typename T>
Foo<T>* Foo<T>::createInstance( unsigned int const in ) {
FooMap::iterator it = mFooMap.find( in );
if ( it != mFooMap.end() ) {
return ( it->second );
} else {
return 0 ;
}
}
template < typename T>
void Foo<T>::Register( unsigned int const in, Foo<T>* factory ) {
mFooMap.insert( FooMap::value_type( in, factory ) );
}
template < typename T>
void Foo<T>::doWork() {}
template <typename T>
class Bar : public Foo <T> {
// Bar( const bar& );
public :
Bar( unsigned int a ) {
Register ( a, this ) ;
}
static Bar mBar;
void doWork () {
sql_field intField ( 1 );
// using Foo<T>::visitor ;
boost::apply_visitor ( typename Foo<T>::visitor(), intField );
// boost::apply_visitor ( Foo<T>::visitor(), intField );
std::cout << "Work done" << std::endl;
}
};
template < typename T>
Bar<T> Bar<T>::mBar;
int main() {
try {
typedef Foo <example_visitor::value_type> FooValueType;
//Bar <example_visitor::value_type> b ( 5 );
Bar <FooValueType> b ( 5 );
Foo <FooValueType>* ptr = Foo<FooValueType>::createInstance ( 5 ) ;
if ( ptr ) {
ptr->doWork();
}
} catch ( const std::exception& e ) {
std::cout << e.what() << std::endl;
}
std::cout << "[done]" << std::endl;
std::cin.get() ;
}
I get compilation error at boost::apply_visitor. The question: How do I pass a dependent type to boost::apply_visitor?
-
February 18th, 2013, 04:37 AM
#2
Re: Dependent type - boost::apply_visitor
Originally Posted by ma740988
I get compilation error at boost::apply_visitor. The question: How do I pass a dependent type to boost::apply_visitor?
Which error do you get?
'visitor' is a member variable of Foo, it is not a type name. So, just use
Code:
boost::apply_visitor(Foo<T>::visitor, intField);
Why did you make the visitor a member variable anyway? You can just create a temporary.
Code:
boost::apply_visitor(T(), intField);
Cheers, D Drmmr
Please put [code][/code] tags around your code to preserve indentation and make it more readable.
As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky
-
February 18th, 2013, 08:45 AM
#3
Re: Dependent type - boost::apply_visitor
Originally Posted by D_Drmmr
'visitor' is a member variable of Foo, it is not a type name. So, just use
Code:
boost::apply_visitor(Foo<T>::visitor, intField);
Produce the error
Foo<T>::visitor': not a valid using-declaration at non-class scope
1> with
1> [
1> T=FooValueType
1> ]
1> main.cpp(103) : while compiling class template member function 'void Bar<T>:oWork(void)'
1> with
1> [
1> T=FooValueType
1> ]
1> main.cpp(120) : see reference to class template instantiation 'Bar<T>' being compiled
1> with
1> [
1> T=FooValueType
1> ]
1>main.cpp(107): error C2064: term does not evaluate to a function taking 0 arguments
1>main.cpp(107): error C2780: 'boost::apply_visitor_delayed_t<Visitor> boost::apply_visitor(Visitor &)' : expects 1 arguments - 2 provided
1> c:\lib\boost\boost_1_49_0\boost/variant/detail/apply_visitor_delayed.hpp(81) : see declaration of 'boost::apply_visitor'
1>main.cpp(107): error C2780: 'Visitor::result_type boost::apply_visitor(const Visitor &,Visitable1 &,Visitable2 &)' : expects 3 arguments - 2 provided
1> c:\lib\boost\boost_1_49_0\boost/variant/detail/apply_visitor_binary.hpp(166) : see declaration of 'boost::apply_visitor'
1>main.cpp(107): error C2780: 'Visitor::result_type boost::apply_visitor(Visitor &,Visitable1 &,Visitable2 &)' : expects 3 arguments - 2 provided
1> c:\lib\boost\boost_1_49_0\boost/variant/detail/apply_visitor_binary.hpp(141) : see declaration of 'boost::apply_visitor'
1>
1>Build FAILED.
1>
1>Time Elapsed 00:00:02.70
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Originally Posted by D_Drmmr
Why did you make the visitor a member variable anyway? You can just create a temporary.
Code:
boost::apply_visitor(T(), intField);
Not following you on 'why did you make the visitor a member variable anyway'. The goal is to have the user pass in their own class type.
Code:
boost::apply_visitor(T(), intField);
Produces the error
1>main.cpp(107): error C2780: 'boost::apply_visitor_delayed_t<Visitor> boost::apply_visitor(Visitor &)' : expects 1 arguments - 2 provided
1> c:\lib\boost\boost_1_49_0\boost/variant/detail/apply_visitor_delayed.hpp(81) : see declaration of 'boost::apply_visitor'
1> main.cpp(103) : while compiling class template member function 'void Bar<T>:oWork(void)'
1> with
1> [
1> T=FooValueType
1> ]
1> main.cpp(120) : see reference to class template instantiation 'Bar<T>' being compiled
1> with
1> [
1> T=FooValueType
1> ]
1>main.cpp(107): error C2780: 'Visitor::result_type boost::apply_visitor(const Visitor &,Visitable1 &,Visitable2 &)' : expects 3 arguments - 2 provided
1> c:\lib\boost\boost_1_49_0\boost/variant/detail/apply_visitor_binary.hpp(166) : see declaration of 'boost::apply_visitor'
1>main.cpp(107): error C2780: 'Visitor::result_type boost::apply_visitor(Visitor &,Visitable1 &,Visitable2 &)' : expects 3 arguments - 2 provided
1> c:\lib\boost\boost_1_49_0\boost/variant/detail/apply_visitor_binary.hpp(141) : see declaration of 'boost::apply_visitor'
1>main.cpp(107): error C2893: Failed to specialize function template 'Visitor::result_type boost::apply_visitor(const Visitor &,Visitable &)'
1> With the following template arguments:
1> 'Foo<T>'
1> with
1> [
1> T=example_visitor::value_type
1> ]
1> 'Foo<T>::sql_field'
1> with
1> [
1> T=FooValueType
1> ]
1>main.cpp(107): error C2893: Failed to specialize function template 'Visitor::result_type boost::apply_visitor(Visitor &,Visitable &)'
1> With the following template arguments:
1> 'Foo<T>'
1> with
1> [
1> T=example_visitor::value_type
1> ]
1> 'Foo<T>::sql_field'
1> with
1> [
1> T=FooValueType
1> ]
1>
1>Build FAILED.
1>
1>Time Elapsed 00:00:02.71
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Compiler is MSVC 2010
-
February 18th, 2013, 12:17 PM
#4
Re: Dependent type - boost::apply_visitor
Originally Posted by ma740988
Produce the error
Foo<T>::visitor': not a valid using-declaration at non-class scope
Please post the full code that produces this error.
Originally Posted by ma740988
Not following you on 'why did you make the visitor a member variable anyway'. The goal is to have the user pass in their own class type.
'visitor' is a member variable of Foo<T> in your code. Why? The class type is passed by the user as template argument. You don't need a member variable for that.
Originally Posted by ma740988
Code:
boost::apply_visitor(T(), intField);
Produces the error
1>main.cpp(107): error C2780: 'boost::apply_visitor_delayed_t<Visitor> boost::apply_visitor(Visitor &)' : expects 1 arguments - 2 provided
Same here, please post the full code.
Cheers, D Drmmr
Please put [code][/code] tags around your code to preserve indentation and make it more readable.
As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky
-
February 18th, 2013, 12:42 PM
#5
Re: Dependent type - boost::apply_visitor
I've _already_ posted the _full_ code. Here's doWork with Foo<T>::visitor as the first argument.
Code:
# include <iostream>
# include <map>
# include <boost/variant.hpp>
# include <boost/mpl/vector.hpp>
# include <boost/mpl/contains.hpp>
# include <boost/bind.hpp>
# include <boost/utility/enable_if.hpp>
// Generic visitor that does magical dispatching of
// types and delegates passes down to your visitor only
// those types specified in a type list.
template <typename Visitor, typename TypeList>
struct lets_see :
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 ) const
{
Visitor::operator () (v);
}
template <typename T>
inline void operator ()
( T v,
typename boost::disable_if <
typename boost::mpl::contains< TypeList, T >::type >::type *dummy = NULL ) const
{}
};
struct nil { int x ; };
struct example_visitor
{
typedef lets_see
< example_visitor,
boost::mpl::vector<nil, char, int > > value_type;
inline void operator () (char v) const {
std::cout << "character detected" << std::endl;
}
inline void operator () (int v) const {
std::cout << "integer detected=" << v << std::endl;
}
inline void operator () (nil v) const {
std::cout << "nil detected=" << v.x << std::endl;
}
};
template < typename T >
class Foo {
protected :
typedef boost::variant <
nil, char, int, double
> sql_field;
T visitor ;
typedef std::map< unsigned int , Foo <T>* > FooMap;
static FooMap mFooMap;
public :
static Foo <T>* createInstance( unsigned int const );
void Register( unsigned int const, Foo< T >* );
virtual void doWork () ;
};
template < typename T>
typename Foo<T>::FooMap Foo<T>::mFooMap;
template < typename T>
Foo<T>* Foo<T>::createInstance( unsigned int const in ) {
FooMap::iterator it = mFooMap.find( in );
if ( it != mFooMap.end() ) {
return ( it->second );
} else {
return 0 ;
}
}
template < typename T>
void Foo<T>::Register( unsigned int const in, Foo<T>* factory ) {
mFooMap.insert( FooMap::value_type( in, factory ) );
}
template < typename T>
void Foo<T>::doWork() {}
template <typename T>
class Bar : public Foo <T> {
// Bar( const bar& );
public :
Bar( unsigned int a ) {
Register ( a, this ) ;
}
static Bar mBar;
void doWork () {
sql_field intField ( 1 );
// using Foo<T>::visitor ;
// boost::apply_visitor ( typename Foo<T>::visitor(), intField );
boost::apply_visitor ( Foo<T>::visitor, intField );
std::cout << "Work done" << std::endl;
}
};
template < typename T>
Bar<T> Bar<T>::mBar;
int main() {
try {
typedef Foo <example_visitor::value_type> FooValueType;
//Bar <example_visitor::value_type> b ( 5 );
Bar <FooValueType> b ( 5 );
Foo <FooValueType>* ptr = Foo<FooValueType>::createInstance ( 5 ) ;
if ( ptr ) {
ptr->doWork();
}
} catch ( const std::exception& e ) {
std::cout << e.what() << std::endl;
}
std::cout << "[done]" << std::endl;
std::cin.get() ;
}
Here's the error:
1>------ Build started: Project: experiment, Configuration: Debug x64 ------
1>Build started 2/18/2013 12:40:52 PM.
1>InitializeBuildStatus:
1> Touching "x64\Debug\experiment.unsuccessfulbuild".
1>ClCompile:
1> main.cpp
1>main.cpp(107): error C2780: 'boost::apply_visitor_delayed_t<Visitor> boost::apply_visitor(Visitor &)' : expects 1 arguments - 2 provided
1> c:\lib\boost\boost_1_49_0\boost/variant/detail/apply_visitor_delayed.hpp(81) : see declaration of 'boost::apply_visitor'
1> main.cpp(103) : while compiling class template member function 'void Bar<T>:oWork(void)'
1> with
1> [
1> T=FooValueType
1> ]
1> main.cpp(120) : see reference to class template instantiation 'Bar<T>' being compiled
1> with
1> [
1> T=FooValueType
1> ]
1>main.cpp(107): error C2780: 'Visitor::result_type boost::apply_visitor(const Visitor &,Visitable1 &,Visitable2 &)' : expects 3 arguments - 2 provided
1> c:\lib\boost\boost_1_49_0\boost/variant/detail/apply_visitor_binary.hpp(166) : see declaration of 'boost::apply_visitor'
1>main.cpp(107): error C2780: 'Visitor::result_type boost::apply_visitor(Visitor &,Visitable1 &,Visitable2 &)' : expects 3 arguments - 2 provided
1> c:\lib\boost\boost_1_49_0\boost/variant/detail/apply_visitor_binary.hpp(141) : see declaration of 'boost::apply_visitor'
1>main.cpp(107): error C2893: Failed to specialize function template 'Visitor::result_type boost::apply_visitor(const Visitor &,Visitable &)'
1> With the following template arguments:
1> 'FooValueType'
1> 'Foo<T>::sql_field'
1> with
1> [
1> T=FooValueType
1> ]
1>main.cpp(107): error C2893: Failed to specialize function template 'Visitor::result_type boost::apply_visitor(Visitor &,Visitable &)'
1> With the following template arguments:
1> 'FooValueType'
1> 'Foo<T>::sql_field'
1> with
1> [
1> T=FooValueType
1> ]
1>
1>Build FAILED.
1>
1>Time Elapsed 00:00:02.69
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
-
February 18th, 2013, 12:44 PM
#6
Re: Dependent type - boost::apply_visitor
Here's the code with your suggestion. Note I commented out "T visitor" in Foo and I've changed the first argument in doWork to "boost::apply_visitor ( T(), intField ) ;
Code:
# include <iostream>
# include <map>
# include <boost/variant.hpp>
# include <boost/mpl/vector.hpp>
# include <boost/mpl/contains.hpp>
# include <boost/bind.hpp>
# include <boost/utility/enable_if.hpp>
// Generic visitor that does magical dispatching of
// types and delegates passes down to your visitor only
// those types specified in a type list.
template <typename Visitor, typename TypeList>
struct lets_see :
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 ) const
{
Visitor::operator () (v);
}
template <typename T>
inline void operator ()
( T v,
typename boost::disable_if <
typename boost::mpl::contains< TypeList, T >::type >::type *dummy = NULL ) const
{}
};
struct nil { int x ; };
struct example_visitor
{
typedef lets_see
< example_visitor,
boost::mpl::vector<nil, char, int > > value_type;
inline void operator () (char v) const {
std::cout << "character detected" << std::endl;
}
inline void operator () (int v) const {
std::cout << "integer detected=" << v << std::endl;
}
inline void operator () (nil v) const {
std::cout << "nil detected=" << v.x << std::endl;
}
};
template < typename T >
class Foo {
protected :
typedef boost::variant <
nil, char, int, double
> sql_field;
// T visitor ;
typedef std::map< unsigned int , Foo <T>* > FooMap;
static FooMap mFooMap;
public :
static Foo <T>* createInstance( unsigned int const );
void Register( unsigned int const, Foo< T >* );
virtual void doWork () ;
};
template < typename T>
typename Foo<T>::FooMap Foo<T>::mFooMap;
template < typename T>
Foo<T>* Foo<T>::createInstance( unsigned int const in ) {
FooMap::iterator it = mFooMap.find( in );
if ( it != mFooMap.end() ) {
return ( it->second );
} else {
return 0 ;
}
}
template < typename T>
void Foo<T>::Register( unsigned int const in, Foo<T>* factory ) {
mFooMap.insert( FooMap::value_type( in, factory ) );
}
template < typename T>
void Foo<T>::doWork() {}
template <typename T>
class Bar : public Foo <T> {
// Bar( const bar& );
public :
Bar( unsigned int a ) {
Register ( a, this ) ;
}
static Bar mBar;
void doWork () {
sql_field intField ( 1 );
// using Foo<T>::visitor ;
// boost::apply_visitor ( typename Foo<T>::visitor(), intField );
boost::apply_visitor ( T(), intField );
std::cout << "Work done" << std::endl;
}
};
template < typename T>
Bar<T> Bar<T>::mBar;
int main() {
try {
typedef Foo <example_visitor::value_type> FooValueType;
//Bar <example_visitor::value_type> b ( 5 );
Bar <FooValueType> b ( 5 );
Foo <FooValueType>* ptr = Foo<FooValueType>::createInstance ( 5 ) ;
if ( ptr ) {
ptr->doWork();
}
} catch ( const std::exception& e ) {
std::cout << e.what() << std::endl;
}
std::cout << "[done]" << std::endl;
std::cin.get() ;
}
Here's the error.
1>------ Build started: Project: experiment, Configuration: Debug x64 ------
1>Build started 2/18/2013 12:42:56 PM.
1>InitializeBuildStatus:
1> Touching "x64\Debug\experiment.unsuccessfulbuild".
1>ClCompile:
1> main.cpp
1>main.cpp(107): error C2780: 'boost::apply_visitor_delayed_t<Visitor> boost::apply_visitor(Visitor &)' : expects 1 arguments - 2 provided
1> c:\lib\boost\boost_1_49_0\boost/variant/detail/apply_visitor_delayed.hpp(81) : see declaration of 'boost::apply_visitor'
1> main.cpp(103) : while compiling class template member function 'void Bar<T>:oWork(void)'
1> with
1> [
1> T=FooValueType
1> ]
1> main.cpp(120) : see reference to class template instantiation 'Bar<T>' being compiled
1> with
1> [
1> T=FooValueType
1> ]
1>main.cpp(107): error C2780: 'Visitor::result_type boost::apply_visitor(const Visitor &,Visitable1 &,Visitable2 &)' : expects 3 arguments - 2 provided
1> c:\lib\boost\boost_1_49_0\boost/variant/detail/apply_visitor_binary.hpp(166) : see declaration of 'boost::apply_visitor'
1>main.cpp(107): error C2780: 'Visitor::result_type boost::apply_visitor(Visitor &,Visitable1 &,Visitable2 &)' : expects 3 arguments - 2 provided
1> c:\lib\boost\boost_1_49_0\boost/variant/detail/apply_visitor_binary.hpp(141) : see declaration of 'boost::apply_visitor'
1>main.cpp(107): error C2893: Failed to specialize function template 'Visitor::result_type boost::apply_visitor(const Visitor &,Visitable &)'
1> With the following template arguments:
1> 'Foo<T>'
1> with
1> [
1> T=example_visitor::value_type
1> ]
1> 'Foo<T>::sql_field'
1> with
1> [
1> T=FooValueType
1> ]
1>main.cpp(107): error C2893: Failed to specialize function template 'Visitor::result_type boost::apply_visitor(Visitor &,Visitable &)'
1> With the following template arguments:
1> 'Foo<T>'
1> with
1> [
1> T=example_visitor::value_type
1> ]
1> 'Foo<T>::sql_field'
1> with
1> [
1> T=FooValueType
1> ]
1>
1>Build FAILED.
1>
1>Time Elapsed 00:00:02.66
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Last edited by ma740988; February 18th, 2013 at 12:45 PM.
Reason: added compilation error
-
February 18th, 2013, 03:38 PM
#7
Re: Dependent type - boost::apply_visitor
Originally Posted by ma740988
Here's the code with your suggestion. Note I commented out "T visitor" in Foo and I've changed the first argument in doWork to "boost::apply_visitor ( T(), intField ) ;
The boost library is at version 1.53. According to your compiler listing, you are using 1.49.
You are 4 versions behind from the latest build. I would suggest you try the latest build of Boost first, as numerous fixes go into boost on each revision, including fixes that affect compiler compilation issues.
Regards,
Paul McKenzie
-
February 18th, 2013, 06:22 PM
#8
Re: Dependent type - boost::apply_visitor
Originally Posted by ma740988
I've _already_ posted the _full_ code. Here's doWork with Foo<T>::visitor as the first argument.
No need for the attitude. The compiler error you posted now is different from the one you posted before. That one didn't make sense for the line of code you posted; it was about a using declaration.
Anyway, try including the correct header: <boost/variant/apply_visitor.hpp>.
Cheers, D Drmmr
Please put [code][/code] tags around your code to preserve indentation and make it more readable.
As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky
-
February 19th, 2013, 10:30 AM
#9
Re: Dependent type - boost::apply_visitor
Greetings Paul, I upgraded to boost 1.53 and the end result is the same. i.e.
main.cpp(108): error C2780: 'boost::apply_visitor_delayed_t<Visitor> boost::apply_visitor(Visitor &)' : expects 1 arguments - 2 provided.
I'm not sure if I understand why the call to apply_visitor is invoking 'applied_visitor_delayed_t'.
-
February 19th, 2013, 11:45 AM
#10
Re: Dependent type - boost::apply_visitor
Originally Posted by ma740988
Greetings Paul, I upgraded to boost 1.53 and the end result is the same. i.e.
main.cpp(108): error C2780: 'boost::apply_visitor_delayed_t<Visitor> boost::apply_visitor(Visitor &)' : expects 1 arguments - 2 provided.
Well the error means what it says. Why are you calling "apply_visitor" with two arguments? I just looked at the boost headers, and indeed, boost::apply_visitor takes one argument.
Code:
template <typename Visitor>
inline apply_visitor_delayed_t<Visitor> apply_visitor(Visitor& visitor)
{
return apply_visitor_delayed_t<Visitor>(visitor);
}
The other "apply_visitor" functions are members of the apply_visitor_delayed_t class. You're calling the global (or boost namespace, non-class version), and that takes only 1 argument.
Code:
boost::apply_visitor ( T(), intField );
This is calling the non-class version, and from what I can see, this is not overloaded to take two or more arguments.
Regards,
Paul McKenzie
Last edited by Paul McKenzie; February 19th, 2013 at 11:47 AM.
-
February 19th, 2013, 12:34 PM
#11
Re: Dependent type - boost::apply_visitor
I think I'm back to my original (sort of) question then. Consider:
Code:
class Foo {
// Generic visitor that does magical dispatching of
// types and delegates passes down to your visitor only
// those types specified in a type list.
template <typename Visitor, typename TypeList>
struct lets_see :
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 ) const
{
Visitor::operator () (v);
}
template <typename T>
inline void operator ()
( T v,
typename boost::disable_if <
typename boost::mpl::contains< TypeList, T >::type >::type *dummy = NULL ) const
{}
};
struct nil { int x ; };
struct example_visitor
{
typedef lets_see
< example_visitor,
boost::mpl::vector<nil, char, int > > value_type;
inline void operator () (char v) const {
std::cout << "character detected" << std::endl;
}
inline void operator () (int v) const {
std::cout << "integer detected=" << v << std::endl;
}
inline void operator () (nil v) const {
std::cout << "nil detected=" << v.x << std::endl;
}
};
protected :
typedef boost::variant <
nil, char, int, double
> sql_field;
example_visitor::value_type visitor ;
typedef std::map< unsigned int , Foo* > FooMap;
static FooMap mFooMap;
public :
static Foo* createInstance( unsigned int const );
void Register( unsigned int const, Foo* );
virtual void doWork () ;
};
Foo::FooMap Foo::mFooMap;
Foo* Foo::createInstance( unsigned int const in ) {
FooMap::iterator it = mFooMap.find( in );
if ( it != mFooMap.end() ) {
return ( it->second );
} else {
return 0 ;
}
}
void Foo::Register( unsigned int const in, Foo* factory ) {
mFooMap.insert( FooMap::value_type( in, factory ) );
}
void Foo::doWork() {}
class Bar : public Foo {
// Bar( const bar& );
public :
Bar( unsigned int a ) {
Register ( a, this ) ;
}
static Bar mBar;
void doWork () {
sql_field intField ( 1 );
boost::apply_visitor ( visitor, intField );
std::cout << "Work done" << std::endl;
}
};
Bar Bar::mBar = 0;
int main() {
try {
Bar b ( 5 );
Foo * ptr = Foo::createInstance ( 5 ) ;
if ( ptr ) {
ptr->doWork();
}
} catch ( const std::exception& e ) {
std::cout << e.what() << std::endl;
}
std::cout << "[done]" << std::endl;
std::cin.get() ;
}
This is the non-templated version of the code that I experimented with which produces the desired result. Trouble is within the Foo class the user defined type ("example_visitor::value_type visitor" ) is hard coded. i.e
Code:
example_visitor::value_type visitor ;
My desire is to accept whatever user defined type is presented as opposed to the hard coded (example_visitor::value_type) version, hence why I went the template route. The question then becomes, how can I my objective?
Thanks in advance.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|