gpt4 book ai didi

c++ - 从 push_front 操作获取常规 MPL 列表

转载 作者:太空狗 更新时间:2023-10-29 22:55:43 24 4
gpt4 key购买 nike

我正在使用 Boost.MPL,我有一个编译时列表 ( boost::mpl::list )。当我推回一个元素时,我得到的东西可能等同于一个列表,但不是 boost::mpl::list。 .

#include <boost/mpl/list.hpp>
int main(){
using l = boost::mpl::push_front<boost::mpl::list<int, double, std::string>, char>::type;
}

lboost::mpl::l_item<mpl_::long_<4>, char, boost::mpl::list3<int, double, std::__cxx11::basic_string<char> > >

如何从 l 转换进入适当的boost::mpl::list<char, int, double, std::string>

在 Boost.Fusion 中我们有 boost::fusion:as_list , 但我在 Boost.MPL 中找不到等效函数。

最佳答案

您可以通过为自定义类型实现 push_back MPL 运算符来实现这一点。

#include <boost/mpl/list.hpp>
#include <boost/mpl/copy.hpp>
#include <boost/mpl/back_inserter.hpp>
#include <string>
#include <type_traits>
#include <tuple>


struct type_pack_tag;

template <typename... T>
struct type_pack
{
using tag = type_pack_tag; // MPL tag

template <typename... U>
using append = type_pack<T..., U...>;

template <template <typename...> class F>
using transfer = F<T...>;
};

namespace boost { namespace mpl {

template <>
struct push_back_impl<type_pack_tag>
{
template <typename TypePack, typename T> struct apply
{
using type = typename TypePack::template append<T>;
};
};

}}

// Just a shortcut
template <template <typename...> class F, typename T>
using transfer_mpl_seq_to_t =
typename boost::mpl::copy<
T, boost::mpl::back_inserter<type_pack<>>
>::type::template transfer<F>;

int main()
{
using l = boost::mpl::push_front<boost::mpl::list<int, double, std::string>, char>::type;

using pack = boost::mpl::copy<l, boost::mpl::back_inserter<type_pack<>>>::type;
static_assert(std::is_same<pack, type_pack<char, int, double, std::string>>::value, "must be equal");
static_assert(std::is_same<pack::transfer<boost::mpl::list>, boost::mpl::list<char, int, double, std::string>>::value, "must be equal");

// Test the shortcut
static_assert(std::is_same<transfer_mpl_seq_to_t<boost::mpl::list, l>, boost::mpl::list<char, int, double, std::string>>::value, "must be equal");
static_assert(std::is_same<transfer_mpl_seq_to_t<std::tuple, l>, std::tuple<char, int, double, std::string>>::value, "must be equal");
}

如果您只需要实例化一个具有 MPL 序列类型的 std::tuple:

#include <boost/mpl/sequence_tag_fwd.hpp>
#include <boost/mpl/list.hpp>
#include <boost/mpl/copy.hpp>
#include <boost/mpl/back_inserter.hpp>
#include <string>
#include <type_traits>
#include <tuple>


struct std_tuple_tag;

namespace boost { namespace mpl {

template <typename... T>
struct sequence_tag<std::tuple<T...>>
{
typedef std_tuple_tag type;
};

}}


namespace boost { namespace mpl {

template <>
struct push_back_impl<std_tuple_tag>
{
template <typename Tuple, typename T> struct apply;

template <typename... T, typename AppendT>
struct apply<std::tuple<T...>, AppendT>
{
using type = std::tuple<T..., AppendT>;
};
};

}}

int main()
{
using l = boost::mpl::push_front<boost::mpl::list<int, double, std::string>, char>::type;

using tpl = boost::mpl::copy<l, boost::mpl::back_inserter<std::tuple<>>>::type;
static_assert(std::is_same<tpl, std::tuple<char, int, double, std::string>>::value, "must be equal");
}

或者更简单:

#include <boost/mpl/list.hpp>
#include <boost/mpl/copy.hpp>
#include <boost/mpl/back_inserter.hpp>
#include <string>
#include <type_traits>
#include <tuple>


namespace boost { namespace mpl {

template <typename... T, typename AppendT>
struct push_back<std::tuple<T...>, AppendT>
{
using type = std::tuple<T..., AppendT>;
};

}}

int main()
{
using l = boost::mpl::push_front<boost::mpl::list<int, double, std::string>, char>::type;

using tpl = boost::mpl::copy<l, boost::mpl::back_inserter<std::tuple<>>>::type;
static_assert(std::is_same<tpl, std::tuple<char, int, double, std::string>>::value, "must be equal");
}

关于c++ - 从 push_front 操作获取常规 MPL 列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50586820/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com