[英]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>();
}
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.