Boost Fusion 变换类型操作和 as_vector
Boost Fusion transform type manipulation and as_vector
我正在尝试了解使用 Fusion 的要点,但被这个简单的示例难倒了:
#include <boost/fusion/include/is_sequence.hpp>
#include <boost/fusion/include/as_vector.hpp>
#include <boost/fusion/include/make_vector.hpp>
#include <boost/fusion/include/transform.hpp>
template< typename T >
struct S {
typedef T type;
};
struct S_f {
template< typename T >
struct result {
typedef typename T::type type;
};
};
int main () {
using namespace boost;
typedef fusion::vector<S<int>> from_type;
BOOST_MPL_ASSERT((fusion::traits::is_sequence< fusion::vector< int > > ));
typedef fusion::result_of::transform< from_type, S_f >::type to_type;
BOOST_MPL_ASSERT((fusion::traits::is_sequence< to_type > ));
typedef fusion::result_of::as_vector< to_type >::type value_type; // error
}
断言通过但 value_type 的 typedef 失败并出现以下错误。我无法资助代码和文档之间的任何差异,也无法在 Whosebug 或 boost 邮件列表的其他地方进行补救。
AFAICT 代码是正确的:应用转换元函数的结果是 transform_view 而 transform_view 是一个序列,如传递的断言所示。然而,在 transform_view 上应用 as_vector 元函数失败。给出了什么?!
感谢任何帮助。我对混合 mpl 不感兴趣。我知道我可以绕过 MPL 和一些关于 SO 的关于类型操作的融合问题有提倡 MPL 的答案。根据文档,我不需要 MPL。
clang++ -std=c++1z -c t.cpp
In file included from main.cpp:4:
In file included from /usr/local/include/boost/fusion/include/transform.hpp:11:
In file included from /usr/local/include/boost/fusion/algorithm/transformation/transform.hpp:11:
In file included from /usr/local/include/boost/fusion/view/transform_view/transform_view.hpp:15:
In file included from /usr/local/include/boost/fusion/view/transform_view/transform_view_iterator.hpp:18:
/usr/local/include/boost/fusion/view/transform_view/detail/value_of_impl.hpp:37:74: error: no type named 'type' in 'boost::mpl::apply<boost::fusion::detail::apply_transform_result<S_f>, S<int>, mpl_::na, mpl_::na, mpl_::na, mpl_::na>'
typedef typename mpl::apply<transform_type, value_type>::type type;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~
/usr/local/include/boost/fusion/iterator/value_of.hpp:52:15: note: in instantiation of template class 'boost::fusion::extension::value_of_impl<boost::fusion::transform_view_iterator_tag>::apply<boost::fusion::transform_view_iterator<boost::fusion::vector_iterator<boost::fusion::vector<S<int>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>, 0>, S_f> >' requested here
: extension::value_of_impl<typename detail::tag_of<Iterator>::type>::
^
/usr/local/include/boost/fusion/container/vector/detail/cpp03/preprocessed/as_vector10.hpp:19:49: note: in instantiation of template class 'boost::fusion::result_of::value_of<boost::fusion::transform_view_iterator<boost::fusion::vector_iterator<boost::fusion::vector<S<int>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>, 0>, S_f> >' requested here
typedef typename fusion::result_of::value_of<I0>::type T0;
^
/usr/local/include/boost/fusion/container/vector/convert.hpp:26:17: note: in instantiation of template class 'boost::fusion::detail::barrier::as_vector<1>::apply<boost::fusion::transform_view_iterator<boost::fusion::vector_iterator<boost::fusion::vector<S<int>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>, 0>, S_f> >' requested here
template apply<typename result_of::begin<Sequence>::type>::type
^
main.cpp:26:32: note: in instantiation of template class 'boost::fusion::result_of::as_vector<boost::fusion::transform_view<boost::fusion::vector<S<int>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>, S_f, boost::fusion::void_> >' requested here
typedef fusion::result_of::as_vector< to_type >::type value_type; // error
^
1 error generated.
模板元编程的问题在于,当您无法满足元函数的先决条件时,您会得到很多无意义的错误。 transform
is that F
is a unary Polymorphic Function Object 上的要求。文档中的解释有点薄弱,但您可以从示例中看出:这是一个您可以使用参数 调用 的对象。也就是说,result_of<F(T)>::type
需要格式正确。
您传递给 transform
的是:
struct S_f {
template< typename T >
struct result {
typedef typename T::type type;
};
};
这不是多态函数对象。它也不是元函数 class。这不是 Boost.Fusion 和 Boost.MPL 都能理解的。特别令人困惑的是 transform<>
元函数是 lazy - 所以看起来你正确地完成了那部分。只有在 as_vector<>
中才真正应用转换,所以看起来这就是失败点。
要将其转换为多态函数对象,只需将嵌套的 result
class 模板更改为调用运算符:
struct S_f {
template< typename T >
typename T::type operator()(T );
};
不需要定义,因为您实际上并没有调用它。通过该修复,您的代码可以编译。
我正在尝试了解使用 Fusion 的要点,但被这个简单的示例难倒了:
#include <boost/fusion/include/is_sequence.hpp>
#include <boost/fusion/include/as_vector.hpp>
#include <boost/fusion/include/make_vector.hpp>
#include <boost/fusion/include/transform.hpp>
template< typename T >
struct S {
typedef T type;
};
struct S_f {
template< typename T >
struct result {
typedef typename T::type type;
};
};
int main () {
using namespace boost;
typedef fusion::vector<S<int>> from_type;
BOOST_MPL_ASSERT((fusion::traits::is_sequence< fusion::vector< int > > ));
typedef fusion::result_of::transform< from_type, S_f >::type to_type;
BOOST_MPL_ASSERT((fusion::traits::is_sequence< to_type > ));
typedef fusion::result_of::as_vector< to_type >::type value_type; // error
}
断言通过但 value_type 的 typedef 失败并出现以下错误。我无法资助代码和文档之间的任何差异,也无法在 Whosebug 或 boost 邮件列表的其他地方进行补救。
AFAICT 代码是正确的:应用转换元函数的结果是 transform_view 而 transform_view 是一个序列,如传递的断言所示。然而,在 transform_view 上应用 as_vector 元函数失败。给出了什么?!
感谢任何帮助。我对混合 mpl 不感兴趣。我知道我可以绕过 MPL 和一些关于 SO 的关于类型操作的融合问题有提倡 MPL 的答案。根据文档,我不需要 MPL。
clang++ -std=c++1z -c t.cpp
In file included from main.cpp:4:
In file included from /usr/local/include/boost/fusion/include/transform.hpp:11:
In file included from /usr/local/include/boost/fusion/algorithm/transformation/transform.hpp:11:
In file included from /usr/local/include/boost/fusion/view/transform_view/transform_view.hpp:15:
In file included from /usr/local/include/boost/fusion/view/transform_view/transform_view_iterator.hpp:18:
/usr/local/include/boost/fusion/view/transform_view/detail/value_of_impl.hpp:37:74: error: no type named 'type' in 'boost::mpl::apply<boost::fusion::detail::apply_transform_result<S_f>, S<int>, mpl_::na, mpl_::na, mpl_::na, mpl_::na>'
typedef typename mpl::apply<transform_type, value_type>::type type;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~
/usr/local/include/boost/fusion/iterator/value_of.hpp:52:15: note: in instantiation of template class 'boost::fusion::extension::value_of_impl<boost::fusion::transform_view_iterator_tag>::apply<boost::fusion::transform_view_iterator<boost::fusion::vector_iterator<boost::fusion::vector<S<int>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>, 0>, S_f> >' requested here
: extension::value_of_impl<typename detail::tag_of<Iterator>::type>::
^
/usr/local/include/boost/fusion/container/vector/detail/cpp03/preprocessed/as_vector10.hpp:19:49: note: in instantiation of template class 'boost::fusion::result_of::value_of<boost::fusion::transform_view_iterator<boost::fusion::vector_iterator<boost::fusion::vector<S<int>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>, 0>, S_f> >' requested here
typedef typename fusion::result_of::value_of<I0>::type T0;
^
/usr/local/include/boost/fusion/container/vector/convert.hpp:26:17: note: in instantiation of template class 'boost::fusion::detail::barrier::as_vector<1>::apply<boost::fusion::transform_view_iterator<boost::fusion::vector_iterator<boost::fusion::vector<S<int>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>, 0>, S_f> >' requested here
template apply<typename result_of::begin<Sequence>::type>::type
^
main.cpp:26:32: note: in instantiation of template class 'boost::fusion::result_of::as_vector<boost::fusion::transform_view<boost::fusion::vector<S<int>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>, S_f, boost::fusion::void_> >' requested here
typedef fusion::result_of::as_vector< to_type >::type value_type; // error
^
1 error generated.
模板元编程的问题在于,当您无法满足元函数的先决条件时,您会得到很多无意义的错误。 transform
is that F
is a unary Polymorphic Function Object 上的要求。文档中的解释有点薄弱,但您可以从示例中看出:这是一个您可以使用参数 调用 的对象。也就是说,result_of<F(T)>::type
需要格式正确。
您传递给 transform
的是:
struct S_f {
template< typename T >
struct result {
typedef typename T::type type;
};
};
这不是多态函数对象。它也不是元函数 class。这不是 Boost.Fusion 和 Boost.MPL 都能理解的。特别令人困惑的是 transform<>
元函数是 lazy - 所以看起来你正确地完成了那部分。只有在 as_vector<>
中才真正应用转换,所以看起来这就是失败点。
要将其转换为多态函数对象,只需将嵌套的 result
class 模板更改为调用运算符:
struct S_f {
template< typename T >
typename T::type operator()(T );
};
不需要定义,因为您实际上并没有调用它。通过该修复,您的代码可以编译。