如何遍历非默认构造类的提升 MPL 列表
How do I loop over a boost MPL list of non-default constructed classes?
我有以下示例:
#include <iostream>
#include <boost/mpl/for_each.hpp>
#include <boost/mpl/list.hpp>
struct one {};
struct two {};
struct three {};
struct four {};
struct five { five() = delete; };
template <typename T>
void print()
{
std::cout << "hello " << typeid(T).name() << std::endl;
}
struct type_printer
{
template <typename T>
void operator()(T)
{
print<T>();
}
};
int main()
{
typedef boost::mpl::list<
one,
two,
three,
four,
five
>::type type_list;
boost::mpl::for_each<type_list>(type_printer());
}
如果我不在列表中包含第五个对象,这绝对可以正常工作,但是一旦我这样做,我就会收到以下错误:
In file included from /usr/local/include/boost_1_56_0/boost/mpl/for_each.hpp:29:0,
from mpldef.cpp:3:
/usr/local/include/boost_1_56_0/boost/utility/value_init.hpp: In constructor ‘boost::initialized<T>::wrapper::wrapper() [with T = five]’:
/usr/local/include/boost_1_56_0/boost/utility/value_init.hpp:109:7: instantiated from ‘boost::initialized<T>::initialized() [with T = five]’
/usr/local/include/boost_1_56_0/boost/utility/value_init.hpp:205:12: instantiated from ‘boost::value_initialized<T>::value_initialized() [with T = five]’
/usr/local/include/boost_1_56_0/boost/mpl/for_each.hpp:81:9: recursively instantiated from ‘static void boost::mpl::aux::for_each_impl<false>::execute(Iterator*, LastIterator*, TransformFunc*, F) [with Iterator = boost::mpl::l_iter<boost::mpl::list4<two, three, four, five> >, LastIterator = boost::mpl::l_iter<boost::mpl::l_end>, TransformFunc = boost::mpl::identity<mpl_::na>, F = type_printer]’
/usr/local/include/boost_1_56_0/boost/mpl/for_each.hpp:81:9: instantiated from ‘static void boost::mpl::aux::for_each_impl<false>::execute(Iterator*, LastIterator*, TransformFunc*, F) [with Iterator = boost::mpl::l_iter<boost::mpl::list5<one, two, three, four, five> >, LastIterator = boost::mpl::l_iter<boost::mpl::l_end>, TransformFunc = boost::mpl::identity<mpl_::na>, F = type_printer]’
/usr/local/include/boost_1_56_0/boost/mpl/for_each.hpp:104:5: instantiated from ‘void boost::mpl::for_each(F, Sequence*, TransformOp*) [with Sequence = boost::mpl::list5<one, two, three, four, five>, TransformOp = boost::mpl::identity<mpl_::na>, F = type_printer]’
/usr/local/include/boost_1_56_0/boost/mpl/for_each.hpp:118:3: instantiated from ‘void boost::mpl::for_each(F, Sequence*) [with Sequence = boost::mpl::list5<one, two, three, four, five>, F = type_printer]’
mpldef.cpp:37:48: instantiated from here
/usr/local/include/boost_1_56_0/boost/utility/value_init.hpp:77:12: error: use of deleted function ‘five::five()’
mpldef.cpp:10:15: error: declared here
有什么办法可以做到这一点吗?我尝试从type_printer
呼叫运算符中删除T
,因此它看起来像这样:void operator()()
,我仍然收到相同的错误。
我通过添加一个类型包装器结构解决了这个问题,就像在 Boost.Hana 中看到的那样。我将其添加到此评论中发现的好主意中,该评论提到使用boost::mpl::transform
将此包装器类型自动添加到列表中的每个项目。
下面详细介绍了我的解决方案:
template <typename T>
struct type_
{
using type = T;
};
template <typename T>
struct add_type_wrapper
{
using type = type_<T>;
};
使用这两种新类型,我将type_printer
函子更改为如下所示:
struct type_printer
{
template <typename T>
void operator()(T)
{
using type_t = typename T::type;
print<type_t>();
}
};
main 中的boost::mpl::for_each
调用现在如下所示:
using boost::mpl::_1;
using wrapped_list = boost::mpl::transform<type_list, add_type_wrapper<_1>>::type;
boost::mpl::for_each<wrapped_list>(type_printer());
感谢您的帮助,我认为这是一个非常好和优雅的解决方案。
您还可以向类型列表中的项目添加一个间接寻址级别,如下所示:
template <typename T>
struct type_ref
{
typedef T type;
}
struct type_printer
{
template <typename T>
void operator()(T)
{
print<T>();
}
template <typename T>
void operator()(type_ref<T>)
{
print<T>();
}
};
int main()
{
typedef boost::mpl::list<
one,
two,
three,
four,
type_ref<five>
>::type type_list;
boost::mpl::for_each<type_list>(type_printer());
}
你可以
自己做一些事情:
namespace detail {
template <typename Tuple>
structure my_for_each_t;
template <typename... Ts>
structure my_for_each_t<boost::mpl::list<Ts...>>
{
template <typename F>
void operator()(F f) const
{
initializer_list<int>{(static_cast<void>(f<Ts>()), 0)...};
}
};
}
template <typename Tuple, typename F>
void my_for_each(F f)
{
detail::my_for_each_t<Tuple>()(f);
}
或者转换列表以添加指向类型的指针,并更改type_printer
:
struct type_printer
{
template <typename T>
void operator()(T*) // pointer added.
{
print<T>();
}
};
相关文章:
- Pybind11:将元组列表从Python传递到C++
- 从链接列表c++中删除一个项目
- 如何(从固定列表中)选择一个数字序列,该序列将与目标数字相加
- C++如何通过用户输入删除列表元素
- 读取文件的最后一行并输入到链接列表时出错
- 复制列表初始化的隐式转换的等级是多少
- LNK2038、MSVS2017 MAGMA的原因列表
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- 没有为自己的结构调用列表推回方法
- 使用简单类型列表实现的指数编译时间.为什么
- 从push_front操作中获取常规 MPL 列表
- Boost mpl列表和auto_test_case_template编译错误
- 为boost mpl列表中的每种类型继承容器
- 从 boost::mpl:vector 类型列表中定义成员变量
- 如何将 MPL 类型列表折叠到可变参数容器中
- boost::mpl:如何为超过 50 个条目的列表生成预生成的头文件
- 如何遍历非默认构造类的提升 MPL 列表
- 使用 MPL 列表扩展提升变体
- Boost::mpl类型列表函数应用程序
- Boost MPL模板列表