Действительно ли возможно генерировать типы со всеми комбинациями аргументов шаблона?

Я думаю, что это - типичная сборка по сравнению со сценарием покупки. Однако я думаю, что в этом случае почти всегда 'покупал' бы, и использовать STL - или лучшее решение (что-то от Повышения, возможно), прежде, чем прокрутить мое собственное. Необходимо фокусировать большую часть усилия на том, что приложение делает, не стандартные блоки, которые это использует.

7
задан Luc Touraille 2 December 2011 в 09:24
поделиться

1 ответ

Если вы действительно хотите сгенерировать вектор всех возможных решений, а затем протестировать их, вам придется использовать препроцессор, чтобы сгенерировать их все за вас.

Однако другое решение может заключаться в использовании генератора: класса-оболочки, который будет создавать экземпляры всех ваших решений и тестировать их. Возможно, вы захотите проконсультироваться с генераторами иерархии Локи (подробно описанными в книге).

// never remember where they put boost::same_type :x
#include <boost/mpl/if.hpp>
#include <boost/mpl/deref.hpp>
#include <boost/mpl/begin.hpp>
#include <boost/mpl/end.hpp>
#include <boost/mpl/next.hpp>

using namespace boost::mpl;

struct None
{
   static void test() {}
};

template <class UIterator, class UTypes,
          class VIterator, class VTypes,
          class WIterator, class WTypes>
class Generator;

template <class UIterator, class UTypes,
          class VIterator, class VTypes,
          class WIterator, class WTypes>
struct Next
{
  // u_begin is not necessary ;)
  // it would be cheaper not to pre-declare all of them since we force evaluation
  // however this dramatically increase the readability
  typedef typename begin<VIterator>::type v_begin;
  typedef typename begin<WIterator>::type w_begin;

  typedef typename next<UIterator>::type u_next;
  typedef typename next<VIterator>::type v_next;
  typedef typename next<WIterator>::type w_next;

  typedef typename end<UIterator>::type u_end;
  typedef typename end<VIterator>::type v_end;
  typedef typename end<WIterator>::type w_end;


  typedef if_< boost::same_type<w_next, w_end>,
               if_< boost::same_type<v_next, v_end>,
                    if_< boost::same_type<u_next, u_end>,
                         None,
                         Generator< u_next, UTypes,
                                    v_begin, VTypes,
                                    w_begin, WTypes >
                    >,
                    Generator< UIterator, UTypes,
                               v_next, VTypes,
                               w_begin, WTypes >
                >,
                Generator< UIterator, UTypes,
                           VIterator, VTypes,
                           w_next, WTypes>
           >::type type;
};

template <class UIterator, class UTypes,
          class VIterator, class VTypes,
          class WIterator, class WTypes>
struct Generator
{
   typedef S< deref<UIterator>::type,
              deref<VIterator>::type,
              deref<WIterator>::type > S_type;

   typedef Next<UIterator, UTypes,
                VIterator, VTypes,
                WIterator, WTypes>::type next_type;

   static void test()
   {
     // test my variation of S
     S_Type my_S;
     test_func(my_S);

     // test the variations of my next and its next and... you get the idea :)
     next_type::test();
   }
};

// And finally
int main(int argc, char* argv[])
{
  typedef Generator< begin<u_types>::type, u_types,
                     begin<v_types>::type, v_types,
                     begin<w_types>::type, w_types > base_generator_type;

  base_generator_type::test();
}

Отказ от ответственности: этот код не был скомпилирован и может не содержать некоторых директив include / typename / use ... тем не менее, я надеюсь, что вы поняли мою точку зрения.

Если у вас есть какое-либо представление о том, что такое шаблоны проектирования, они очень похожи на «декоратор» или «составной» дизайн в том, что касается добавления еще одного цикла тестов на каждом уровне шага.

Я также хотел бы отметить, что для этого требуется более 50 строк кода ...

9
ответ дан 7 December 2019 в 01:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: