Building a list of types at compile time - no C ++ 11

I would like to make this exact to get a list of types / classes. But I can not use C ++ 11. Any suggestion, how can I add a type to the list of templates?

Edit: the code I would like to do:

#include <iostream>
#include <typeinfo>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/push_back.hpp>
#include <boost/mpl/for_each.hpp>

using namespace std;

class A {};
class B {};
class C {};

typedef boost::mpl::vector<> type1;
// supposed I'd like to have this as a #define macro so someone can call
// REGISTER_CLASS(A) and push the type into a list
typedef boost::mpl::push_back<type1, A> type2;
typedef boost::mpl::push_back<type2, B> type3;
typedef boost::mpl::push_back<type3, C> type4;

template <typename T> struct wrap {};

struct Print
{
      template <typename T> void operator()( wrap<T> t ) const
      {
            cout << typeid( T ).name() << endl;
      }
};

int main()
{
      // this doesn't compile because type4 is a sequence of sequence
      // supposed, I need to "flatten" this list so it eqv to vector<A,B,C>
      boost::mpl::for_each<type4, wrap<boost::mpl::placeholders::_1> >( Print() );

      // second problem is that I'd like to have typedef of 1 typelist only, not
      // type1, type2, ... typeN, since I don't know the exact number of classes

      return 0;
}
+2
source share
1 answer

Firstly, the actual problem why your code does not compile is that you are typing operations, not their results. Change it like this:

typedef boost::mpl::push_back<type1, A>::type type2;
typedef boost::mpl::push_back<type2, B>::type type3;
typedef boost::mpl::push_back<type3, C>::type type4;

Now a more general look at why you need typedefs.

(, ) "", "" ++. ++ . .

, , . , :

vector<int> v;
v.push(4);
v.push(7);
v.push(42);
process(&v);
print(v);

:

v = vector<int>;
v1 = v.push(4);
v2 = v1.push(7);
v3 = v2.push(42);
v4 = process(v3);
print(v4);

, , - :

print(process(vector<int>().push(4).push(7).push(42)));

(LISP -) :

(print (process (push (push (push (vector<int>) 4) 7) 42)))

, , .

++ Boost.MPL, , T ( MPL) v - boost::mpl::push_back<v, T>::type , " T ". DRY, typedef " T ".


, , REGISTER_CLASS , . - ( Boost.Preprocessor).

Boost.Preprocessor . REGISTER_CLASS #include d, . - :

internal_register.hpp

//This file MUST NOT have include guards

#ifndef CLASS_TO_REGISTER
  #error You must define CLASS_TO_REGISTER before executing REGISTER_CLASS()
#endif

typedef boost::mpl::push_back<
  CURRENT_TYPELIST(),
  CLASS_TO_REGISTER
>::type BOOST_PP_CAT(registered, BOOST_PP_INC(BOOST_PP_SLOT(1)));

#undef CLASS_TO_REGISTER

#define BOOST_PP_VALUE BOOST_PP_SLOT(1) + 1
#include BOOST_PP_ASSIGN_SLOT(1)

registration.hpp

typedef boost::mpl::vector<>::type registered0;

#define BOOST_PP_VALUE 0
#include BOOST_PP_ASSIGN_SLOT(1)

#define REGISTER_CLASS() "internal_register.hpp"

#define CURRENT_TYPELIST() BOOST_PP_CAT(registered, BOOST_PP_SLOT(1))

main.cpp ( ):

#include "registration.hpp"

class A {};
class B {};
class C {};

#define CLASS_TO_REGISTER A
#include REGISTER_CLASS()

#define CLASS_TO_REGISTER B
#include REGISTER_CLASS()

#define CLASS_TO_REGISTER C
#include REGISTER_CLASS()

template <typename T> struct wrap {};

struct Print
{
      template <typename T> void operator()( wrap<T> t ) const
      {
            cout << typeid( T ).name() << endl;
      }
};

int main()
{
      boost::mpl::for_each<CURRENT_TYPELIST(), wrap<boost::mpl::placeholders::_1> >( Print() );

      return 0;
}

, ( , , ). .

+5

Source: https://habr.com/ru/post/1668976/


All Articles