【问题标题】:Using boost::mpl::find_if with custom predicate使用带有自定义谓词的 boost::mpl::find_if
【发布时间】:2017-06-23 12:49:26
【问题描述】:

给定

struct A {};
struct B {};
struct C {C(B) {}};
struct D : B {};
struct E {operator A() const {return A();}};
struct F {};

using AllowedTypes = boost::mpl::vector<A, C>;

我正在尝试实现一个谓词 is_allowed_type 以便

static_assert(is_allowed_type<A>::value, "A is in AllowedTypes");
static_assert(is_allowed_type<B>::value, "C is constructible from B");
static_assert(is_allowed_type<C>::value, "C is in AllowedTypes");
static_assert(is_allowed_type<D>::value, "D inherits from B, from which C is constructible");
static_assert(is_allowed_type<E>::value, "E is convertible to A");
static_assert(!is_allowed_type<F>::value, "F is not convertible to A nor C");

如果谓词的参数可转换为AllowedTypes 中的一种类型,则谓词必须返回真。

这是我想出的。

template <typename T>
struct is_allowed_type
{
    using I = boost::mpl::find_if<AllowedTypes, std::is_convertible<T, boost::mpl::_>>;
    using End = boost::mpl::end<AllowedTypes>;
    enum {value = !std::is_same<I, End>::value};
};

最后一个断言失败。我的is_allowed_type 有什么问题?

【问题讨论】:

    标签: c++ typetraits boost-mpl


    【解决方案1】:

    我在写问题时找到了答案,但由于我很难找到有关该主题的材料,所以我将其发布。

    is_allowed_type 中的迭代器定义缺少 ::type。正确的实现是

    template <typename T>
    struct is_allowed_type
    {
        using I = typename boost::mpl::find_if<AllowedTypes, std::is_convertible<T, boost::mpl::_>>::type;
        using End = typename boost::mpl::end<AllowedTypes>::type;
        enum {value = !std::is_same<I, End>::value};
    };
    

    【讨论】:

    • 无论如何我仍然不明白像boost::mpl::_ 这样的占位符如何与不是专门为它们设计的元函数一起工作,比如std::is_convertible...std::is_convertible&lt;T, boost::mpl::_&gt; 不是怎么发生的立即评估,产生一个常数?有人能解释一下吗?
    • 这就像黑魔法,对吧?无论如何,MPL 很难阅读、编写和推理。将Boost.Hana 视为 C++ 元编程的前进方向,因为它不需要所有内容都仅存在于模板中——“我们需要更多的元编程,但需要更少的 模板 元编程。”请参阅 Louis Dionne 的 ACCU talk (slides) 或他的 other talks
    • 哇,我从未听说过/读过 Boost.Hana。这种新方法确实很有趣,但我想知道为什么 Boost 人(其中许多人属于 C++ 标准化委员会)仍在探索基于库的元编程方法,而不是语言嵌入的新功能。
    • 简单——MPL(和 Boost.Fusion,它是 Hana 的另一个前身)在 C++03 中工作,而 Hana 需要 C++11/14。 C++11 之前的元编程必须使用 MPL 之类的东西。虽然现有的代码库可能仍需要维护现有的 MPL 代码,而使用旧编译器(例如 gcc 5.x)的新代码库可能必须在需要元编程的地方使用 MPL,但如果你有的话,现在有更好的方法更新的编译器。嘘!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多