Я думаю, что это - типичная сборка по сравнению со сценарием покупки. Однако я думаю, что в этом случае почти всегда 'покупал' бы, и использовать STL - или лучшее решение (что-то от Повышения, возможно), прежде, чем прокрутить мое собственное. Необходимо фокусировать большую часть усилия на том, что приложение делает, не стандартные блоки, которые это использует.
Если вы действительно хотите сгенерировать вектор всех возможных решений, а затем протестировать их, вам придется использовать препроцессор, чтобы сгенерировать их все за вас.
Однако другое решение может заключаться в использовании генератора: класса-оболочки, который будет создавать экземпляры всех ваших решений и тестировать их. Возможно, вы захотите проконсультироваться с генераторами иерархии Локи (подробно описанными в книге).
// 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 строк кода ...