我正在尝试学习C ++模板元编程。给定一个boost :: mpl ::类的向量,我想计算静态成员变量具有特定值的该类的索引。
我找到了一个似乎有用的解决方案。但是,为了正确编译,我需要一些看起来不必要的奇怪的“包装类”。这是我的代码:
#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 :(得分:1)
根据错误消息,您似乎需要类似
的内容mpl::int_< mpl::at<l, mpl::placeholders::_2>::type::x > >
答案 1 :(得分:1)
我们需要将元函数传递给if_,这可以在折叠展开后进行延迟评估。
代表
mpl::int_< mpl::at<l, mpl::placeholders::_2>::type::x >
它会立即进行评估,从而产生无法找到&#39; x&#39;从表达。
您可以尝试使用服装测试函数而不是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;
};