Is it possible to iterate an mpl::vector at run time without instantiating the types in the vector?

前端 未结 6 1339
青春惊慌失措
青春惊慌失措 2020-12-25 14:27

Generally, I would use boost::mpl::for_each<>() to traverse a boost::mpl::vector, but this requires a functor with a template function declar

6条回答
  •  时光取名叫无心
    2020-12-25 14:57

    Here is an alternative solution highly inspired from Luc Touraille's answer.

    This version is done using Metafunction classes instead of functions which allows the static_for_each to be called even outside of function scopes (useful if the job has to be totally done at compiletime so you have no unnecessary functions called at runtime).

    Furthermore it gives more interaction thanks to the first and last typedefs, allowing to get information out of the loop if necessary, a little like the way a return works for a function.

    You can also access the previous iteration result within each iteration thanks to the second template parameter Previous passed to the metafunction class F.

    Finally you can provide data to the loop process using the Initial template parameter, it will be given as the value of the Previous parameter of the first iteration.

    # include 
    # include 
    # include 
    
    namespace detail_static_for_each
    {
      // Loop
      template
      struct static_for_each
      {
      private:
        typedef typename Begin::type                                current_type;
    
      public:
        typedef typename boost::mpl::apply::type             first;
        typedef typename static_for_each::type, End, F, first>::last   last;
      };
    
      // End of loop
      template
      struct static_for_each
      {
      public:
        typedef Last    first;
        typedef Last    last;
      };
    
    } // namespace detail_static_for_each
    
    // Public interface
    template
    struct  static_for_each
    {
    private:
      typedef typename boost::mpl::begin::type        begin;
      typedef typename boost::mpl::end::type          end;
    
      typedef typename detail_static_for_each::static_for_each  loop;
    
    public:
      typedef typename  loop::first                 first;
      typedef typename  loop::last                  last;
    };
    

    Here is a simple example that both gives and retrieves data :

    # include 
    
    # include 
    
    # include 
    # include 
    
    # include "static_for_each.hpp"
    
    struct is_there_a_float                                                                                                                                                                                              
    {                                                                                                                                                                                                                    
        template                                                                                                                                                     
        struct apply                                                                                                                                                                                                       
        {                                                                                                                                                                                                                  
            typedef typename boost::mpl::if_< PreviousIterationType,                                                                                                                                                         
                                              PreviousIterationType,                                                                                                                                                         
                                              boost::is_same >::type    type;                                                                                                                        
        };                                                                                                                                                                                                                 
    };
    
    struct  test                                                                                                                                                                                                         
    {                                                                                                                                                                                                                    
        typedef boost::mpl::vector< char, long, long, double, float, int, char > sequence;                                                                                                                                 
    
        typedef static_for_each::last    found;                                                                                                               
    };
    
    int     main(void)                                                                                                                                                                                                   
    {                                                                                                                                                                                                                    
        std::cout << std::boolalpha << test::found::value << std::endl;                                                                                                                                                    
    
        return (0);                                                                                                                                                                                                        
    }
    

    These features makes the use of static_for_each more similar to the use of common runtime loops (while, for, BOOST_FOREACH ...) as you can interact more directly with the loop.

提交回复
热议问题