如何使用std :: tuple类型与boost :: mpl算法? [英] How to use std::tuple types with boost::mpl algorithms?

查看:377
本文介绍了如何使用std :: tuple类型与boost :: mpl算法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

boost :: mpl 算法似乎无法处理 std :: tuple 类型框,例如,以下不编译(boost-1.46.0,g ++快照2011-02-19):

The boost::mpl algorithms seem not to be able to work on std::tuple types out of the box, e.g., the following does not compile (boost-1.46.0, g++ snapshot 2011-02-19):

#include <tuple>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/contains.hpp>

namespace mpl=boost::mpl;

typedef mpl::vector<int,float,bool> types;
static_assert(mpl::contains<types, float>::value, "vector contains bool");

typedef std::tuple<int,float,bool> types2;
// the following does not compile:
// error: no class template named ‘apply’ in ‘struct boost::mpl::contains_impl<boost::mpl::non_sequence_tag>’
static_assert(mpl::contains<types2, float>::value, "tuple contains bool");

最简单的方法是使 boost :: mpl 算法适用于 std :: tuple

What is the easiest way to make the boost::mpl algorithms work on std::tuple?


  • evtl. boost :: fusion 提供此功能(因为 boost :: tuple

  • 如果没有,是否可以将 boost :: tuple 的融合实现继承到 std :: tuple 很容易?

  • 如果没有,我真的必须实现 MPL文档中列出的所有内部元函数,还是那些足够了? (文档只是说许多内部元函数提供了一个默认的实现,将在大多数情况下工作,但不清楚哪些精确的。一些只提供开始和结束的测试没有。

  • Does evtl. boost::fusion provide this functionality (as it does so for boost::tuple)?
  • If not, would it be possible to carry over the fusion implementation for boost::tuple to std::tuple easily?
  • If not either, do I really have to implement all the intrinsic metafunctions listed in the MPL documentation or which ones would be sufficient? (The docs only says "many of intrinsic metafunctions offer a default implementation that will work in majority of cases", but it is not clear which ones exactly. And some tests with just providing begin and end did not lead me anywhere).

推荐答案

从std :: tuple转换为boost类型,成为最简单的方法

Converting from std::tuple to boost types and back seems to be the easiest way

#include <iostream>
#include <tuple>
#include <type_traits>
#include <boost/mpl/if.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/vector.hpp>

namespace mpl = boost::mpl;

template<typename Sequence, typename T>
struct push_front;

template<template<typename...> class Sequence, typename T, typename ... Args>
struct push_front< Sequence<Args...>,T> {
  typedef Sequence<T, Args...> type;
};

template<template<typename...> class To, typename From> struct tuple_change;

template<template<typename...> class To, template<typename...> class From, typename ... Args>
struct tuple_change<To, From<Args...>>
{
  typedef To<Args...> type;
};

template<typename Sequence, size_t N>
struct at : std::tuple_element<N,Sequence> { };

template<typename Sequence>
struct empty;

template<template<typename...> class Sequence, typename ... Args>
struct empty<Sequence<Args...>> {
  typedef Sequence<> type;
};

template<
  size_t N,
  typename Sequence,
  template<typename> class Pred,
  typename ... Args >
struct while_impl
{
  typedef typename mpl::if_c<
    Pred<
        typename at<Sequence, sizeof...(Args) - N -1>::type
    >::value,
    typename push_front<
        typename while_impl<N-1, Sequence, Pred, Args...>::type, 
            typename at<Sequence,sizeof...(Args)-N-1>::type
    >::type,
    typename empty< Sequence > ::type
  >::type type;
};

template<
  typename Sequence,
  template<typename> class Pred,
  typename ... Args >
struct while_impl<-1, Sequence, Pred, Args...>
: empty<Sequence> {
};


template<
  typename Sequence,
  template<typename> class Pred>
struct while_;

template<
  template<typename...> class Sequence,
  template<typename> class Pred,
  typename ... Args >
struct while_< Sequence<Args...>, Pred >
{
  typedef typename while_impl<sizeof...(Args)-1, Sequence<Args...>, Pred, Args...>::type type;
};

template<typename T>
struct not_na : mpl::not_< std::is_same<mpl_::na, T> >
{ };

template<template<typename...> class To, typename From>
struct to_boost;

template<template<typename...> class To, typename...Args >
struct to_boost<To, std::tuple<Args...> > :
  tuple_change< mpl::vector, std::tuple<Args...> >
{ };

template< typename From >
struct to_std;

template<template<typename...> class From, typename...Args >
struct to_std< From<Args...> > :
   while_<typename tuple_change< std::tuple, From<Args...> >::type, not_na>
{ };

static_assert(
std::is_same<
    mpl::vector< char, int, bool>,
    typename to_boost<mpl::vector, std::tuple<char, int, bool> >::type
  >::value,
"tuple_change to boost failed");

static_assert(
  std::is_same<
    std::tuple< char, int, bool>,
    typename to_std< mpl::vector<char, int, bool> >::type
  >::value,
"tuple_change from boost failed");

int main(){ return 0;}



MacOSx上的boost_1_46_0和g ++ - 4.5

Ubuntu 10.10上的boost_1_45_0和g ++ - 4.5

*tested with:
boost_1_46_0 and g++-4.5 on MacOSx
boost_1_45_0 and g++-4.5 on Ubuntu 10.10

这篇关于如何使用std :: tuple类型与boost :: mpl算法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆