boost-mpl, fold и placeholder, выбрать класс из вектора

Я пытаюсь изучить метапрограммирование шаблона C ++. Учитывая boost :: mpl :: vector классов, я хочу вычислить индекс этого класса, где статическая переменная-член имеет определенное значение.

Я нашел решение, которое, кажется, работает. Однако для правильной компиляции мне нужны странные «классы-обертки», которые кажутся ненужными. Вот мой код:

#include <iostream>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/size.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/range_c.hpp>

using namespace boost;

template<typename T>
struct get_ind {
typedef mpl::int_<T::type::value> type;
};

template <typename T>
struct get_x {
typedef mpl::int_<T::x> type;
};

template<typename l>
struct clist {
typedef mpl::range_c<int, 0, mpl::size<l>::type::value > indices;
typedef mpl::fold<
indices, mpl::size<l>,
mpl::if_<
is_same<

// HERE:
get_x<mpl::at<l, get_ind<mpl::placeholders::_2> > >
//
//  mpl::int_< mpl::at<l, mpl::placeholders::_2>::type::x >
//  mpl::int_<mpl::at<l, mpl::placeholders::_2> >::x >
, mpl::int_<1>   >
,
mpl::placeholders::_2, mpl::placeholders::_1 >
> index;
};struct A {
static const int x = 1;
};

struct B {
static const int x = 0;
};int main(int argc, char*argv[]) {

typedef boost::mpl::vector<A, B> classes;
typedef clist<classes> classlist;

std::cout << "result " << classlist::index::type::value<<std::endl;
return 0;
}

РЕДАКТИРОВАТЬ:

Теперь я убедился, что он на самом деле компилируется. Тем не менее, предложение Стивена также не работает. Для этого изменения я получаю эти ошибки:

test.cpp: In instantiation of ‘clist<boost::mpl::vector<A, B, mpl_::na, mpl_::na,
mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_
::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na> >’:
test.cpp:56:   instantiated from here
test.cpp:38: error: ‘x’ is not a member of ‘mpl_::void_’
test.cpp: In function ‘int main(int, char**)’:
test.cpp:56: error: ‘classlist::index’ is not a class or namespace

Может ли кто-нибудь объяснить мне, что не так в моем первом решении (закомментировано) и как мне избежать необходимости использовать классы get_x и get_ind?

большое спасибо

0

Решение

Судя по сообщению об ошибке, похоже, вам нужно что-то вроде

mpl::int_< mpl::at<l, mpl::placeholders::_2>::type::x > >
1

Другие решения

Нам нужно передать метафункцию в if_, которая позволяет выполнять ленивую оценку после раскрытия фолда.

за

mpl::int_< mpl::at<l, mpl::placeholders::_2>::type::x >

он немедленно выполнит оценку, которая вызвала ошибку, которая не может найти ‘x’ из выражения.

Вы можете попробовать использовать костюмированную тестовую функцию вместо is_same, например,

template <typename T, typename V>
struct has_value
: mpl::bool_<T::x == V::value>
{};

template<typename l>
struct clist {
typedef mpl::range_c<int, 0, mpl::size<l>::type::value > indices;
typedef mpl::fold<
indices, mpl::size<l>,
mpl::if_<
has_value<
mpl::at<l, mpl::placeholders::_2>
, mpl::int_<1>   >
,
mpl::placeholders::_2, mpl::placeholders::_1 >
> index;
};
1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector