Dependent type - boost::apply_visitor
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 11 of 11

Thread: Dependent type - boost::apply_visitor

  1. #1
    Join Date
    Dec 2005
    Posts
    6

    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?

  2. #2
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,016

    Re: Dependent type - boost::apply_visitor

    Quote Originally Posted by ma740988 View Post
    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

  3. #3
    Join Date
    Dec 2005
    Posts
    6

    Re: Dependent type - boost::apply_visitor

    Quote Originally Posted by D_Drmmr View Post
    '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>::doWork(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 ==========

    Quote Originally Posted by D_Drmmr View Post
    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>::doWork(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

  4. #4
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,016

    Re: Dependent type - boost::apply_visitor

    Quote Originally Posted by ma740988 View Post
    Produce the error
    Foo<T>::visitor': not a valid using-declaration at non-class scope
    Please post the full code that produces this error.
    Quote Originally Posted by ma740988 View Post
    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.
    Quote Originally Posted by ma740988 View Post
    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

  5. #5
    Join Date
    Dec 2005
    Posts
    6

    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>::doWork(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 ==========

  6. #6
    Join Date
    Dec 2005
    Posts
    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>::doWork(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

  7. #7
    Join Date
    Apr 1999
    Posts
    27,444

    Re: Dependent type - boost::apply_visitor

    Quote Originally Posted by ma740988 View Post
    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

  8. #8
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,016

    Re: Dependent type - boost::apply_visitor

    Quote Originally Posted by ma740988 View Post
    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

  9. #9
    Join Date
    Dec 2005
    Posts
    6

    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'.

  10. #10
    Join Date
    Apr 1999
    Posts
    27,444

    Re: Dependent type - boost::apply_visitor

    Quote Originally Posted by ma740988 View Post
    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.

  11. #11
    Join Date
    Dec 2005
    Posts
    6

    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
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center