使用 boost::mpl::lambda 基于 static const 成员变量从 boost::mpl::list 中删除类型

发布于 2024-09-07 01:01:22 字数 1672 浏览 5 评论 0原文

我有一个类型列表定义为:

typedef boost::mpl::list<Apple, Pear, Brick> OriginalList;

我想创建第二个不包含任何水果的列表,即从第一个列表形成的结果列表将包含单个类型 Brick。水果是通过类型中定义的静态 const 变量来标识的,例如:

struct Apple
{
    static const bool IsFruit = true;
};

我目前有一个解决方案,涉及创建元函数类并使用 boost::mpl::remove_if。我相信我应该能够通过使用 boost::mpl::lambda 来消除对单独的 RemoveFruit 结构的需要,从而使其更加优雅。关于如何执行此操作有什么建议吗?

目前的完整代码:

include <boost/static_assert.hpp>
#include <boost/mpl/list.hpp>
#include <boost/mpl/remove_if.hpp>
#include <boost/mpl/size.hpp>

#include <iostream>

struct Apple
{
  static const bool IsFruit = true;
};

struct Pear
{
  static const bool IsFruit = true;
};

struct Brick
{
  static const bool IsFruit = false;
};

typedef boost::mpl::list<Apple, Pear, Brick> OriginalList;
BOOST_STATIC_ASSERT(boost::mpl::size<OriginalList>::type::value == 3);

// This is what I would like to get rid of:
struct RemoveFruit
{
  template <typename T>
  struct apply
  {
    typedef boost::mpl::bool_<T::IsFruit> type;
  };
};

// Assuming I can embed some predicate directly in here?
typedef boost::mpl::remove_if<
  OriginalList,
  RemoveFruit
  >::type NoFruitList;

BOOST_STATIC_ASSERT(boost::mpl::size<NoFruitList>::type::value == 1);

int main()
{
  std::cout << "There are " << boost::mpl::size<OriginalList>::type::value << " items in the original list\n";
  std::cout << "There are " << boost::mpl::size<NoFruitList>::type::value << " items in the no fruit list\n";


  return 0;
}

I have a list of types defined as:

typedef boost::mpl::list<Apple, Pear, Brick> OriginalList;

I would like to create a second list that does not contain any fruit, i.e. the resultant list formed from the first list would contain a single type Brick. Fruit is identified through a static const variable defined within the types, e.g.:

struct Apple
{
    static const bool IsFruit = true;
};

I currently have a solution that involves creating a meta-function class, and using boost::mpl::remove_if. I believe I should be able to make this more elegant by using boost::mpl::lambda to remove the need for the separate RemoveFruit struct. Any suggestions on how to do this?

Full code as it currently stands:

include <boost/static_assert.hpp>
#include <boost/mpl/list.hpp>
#include <boost/mpl/remove_if.hpp>
#include <boost/mpl/size.hpp>

#include <iostream>

struct Apple
{
  static const bool IsFruit = true;
};

struct Pear
{
  static const bool IsFruit = true;
};

struct Brick
{
  static const bool IsFruit = false;
};

typedef boost::mpl::list<Apple, Pear, Brick> OriginalList;
BOOST_STATIC_ASSERT(boost::mpl::size<OriginalList>::type::value == 3);

// This is what I would like to get rid of:
struct RemoveFruit
{
  template <typename T>
  struct apply
  {
    typedef boost::mpl::bool_<T::IsFruit> type;
  };
};

// Assuming I can embed some predicate directly in here?
typedef boost::mpl::remove_if<
  OriginalList,
  RemoveFruit
  >::type NoFruitList;

BOOST_STATIC_ASSERT(boost::mpl::size<NoFruitList>::type::value == 1);

int main()
{
  std::cout << "There are " << boost::mpl::size<OriginalList>::type::value << " items in the original list\n";
  std::cout << "There are " << boost::mpl::size<NoFruitList>::type::value << " items in the no fruit list\n";


  return 0;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

凉栀 2024-09-14 01:01:22

我认为您能做的最好的事情就是定义一个 IsFruit 结构,例如

template  <typename T> struct isFruit : boost::mpl::bool_<T::IsFruit> {};

然后您可以将您的无水果列表定义为

typedef boost::mpl::remove_if<
  OriginalList,
  boost::mpl::lambda< isFruit< boost::mpl::_1 > >::type
  >::type NoFruitList;

需要附加结构才能访问类中的 IsFruit 字段。

请注意,如果您想完全删除附加结构,则必须重命名其他类的布尔成员。如果遵循 boost::mpl 约定并将它们称为 value 而不是 IsFruit,则可以将 NoFruitList 定义为

typedef boost::mpl::remove_if<
      OriginalList,
      boost::mpl::lambda<boost::mpl::_1>::type
      >::type NoFruitList;

I think the best you can do is to define an IsFruit struct like

template  <typename T> struct isFruit : boost::mpl::bool_<T::IsFruit> {};

And then you can define your no-fruit list as

typedef boost::mpl::remove_if<
  OriginalList,
  boost::mpl::lambda< isFruit< boost::mpl::_1 > >::type
  >::type NoFruitList;

The additional struct is needed to get access to the IsFruit field in your classes.

Note that if you want to get rid of the additional struct entirely, you'll have to rename the boolean members of your other classes. If you follow the boost::mpl convention and call them value instead of IsFruit, you can define NoFruitList as

typedef boost::mpl::remove_if<
      OriginalList,
      boost::mpl::lambda<boost::mpl::_1>::type
      >::type NoFruitList;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文