【问题标题】:How to use nested metafunctions in Boost.MPL?如何在 Boost.MPL 中使用嵌套元函数?
【发布时间】:2016-05-31 16:14:03
【问题描述】:

我有一个简单的元函数:

template <typename T>
using is_const_lvalue_reference = mpl::and_<
    std::is_lvalue_reference<T>,
    std::is_const<typename std::remove_reference<T>::type>
>;

显然,如果 T 是 MPL 占位符,则它不起作用,因为 remove_reference 被评估为占位符类而不是替代类型。如何正确执行此操作才能在 MPL 算法中使用此元函数?

更新:建议的解决方案是用结构替换别名,这将延迟std::remove_reference 中的模板实例化。问题是,如何在不使用任何辅助结构的情况下延迟内联实例化?

template <typename Sequence>
using are_const_lvalue_references = mpl::fold<
    Sequence,
    mpl::true_,
    mpl::and_<
        mpl::_1,
        mpl::and_<
            std::is_lvalue_reference<mpl::_2>,
            std::is_const<typename std::remove_reference<mpl::_2>::type>
        >
    >
>;

这个例子显然会因为同样的原因而失败。我应该改变什么才能使它正确?

【问题讨论】:

    标签: c++ boost metaprogramming template-meta-programming boost-mpl


    【解决方案1】:

    以这种方式将类型特征写为别名是行不通的,因为它们会立即实例化。 is_const_lvalue_reference&lt;_1&gt; 正好是 mpl::and_&lt;std::is_lvalue_reference&lt;_1&gt;, std::is_const&lt;_1&gt;&gt;(因为 _1 不是引用类型)——总是 false 因为左值引用不是 const。写false_ 的方式相当棘手!

    相反,您必须延迟实例化。只需让你的类型特征继承自 mpl::and_ 而不是别名:

    template <class T>
    struct is_const_lvalue_reference
        : mpl::and_<
            std::is_lvalue_reference<T>,
            std::is_const<std::remove_reference_t<T>>
            >
    { };
    

    这样,std::remove_reference_t&lt;T&gt; 不会被实例化,除非我们实际尝试访问 is_const_lvalue_reference&lt;T&gt;::type - 这在 _1 被替换为 apply 中的真实类型之前不会发生。


    另外,由于apply&lt;&gt; 将在找到占位符的地方调用::type,您可以自己放弃对::type 的显式调用。所以这行得通:

    BOOST_MPL_ASSERT(( mpl::apply<
        std::is_const<std::remove_reference<_1>>,
        int const&
        > ));
    

    或者用原来的表达方式:

    BOOST_MPL_ASSERT(( mpl::apply<
        mpl::and_<
            std::is_lvalue_reference<_1>,
            std::is_const<std::remove_reference<_1>>
        >,
        int const&
        > ));
    

    请注意,这种构造虽然不能用作类型特征。

    【讨论】:

    • 谢谢,它是这样工作的,但是如果我放弃结构并就地使用表达式(在更大的 MPL 表达式中),我仍然会遇到同样的问题。我该如何处理?
    • @lizarisk 我不知道那是什么意思。也许问一个新的具体问题?
    • 我的意思是,我知道将别名转换为结构会延迟模板实例化并解决问题,但是如果我只想使用内联表达式(即在这种情况下为 remove_reference)怎么办?我应该如何延迟模板实例化?
    • @lizarisk 已更新。
    • 谢谢!我放弃了这个解决方案,因为我试图将它用作类型特征和占位符表达式的一部分,这让我出于某种原因感到困惑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-30
    • 2021-11-01
    • 2011-09-06
    • 1970-01-01
    • 2018-03-15
    相关资源
    最近更新 更多