如何使用boost MPL有条件地添加?

时间:2016-02-26 18:48:25

标签: c++ c++11 boost c++14

我试图根据提供的类型参数来评估bitset的值。我现在的功能就是:

template <class Set, class PartialSet>
constexpr auto tupleBitset() {
    using type = 
        typename mpl::fold<
            PartialSet,
            mpl::integral_c<unsigned long long, 0>,
            mpl::eval_if<
                mpl::has_key<Set, mpl::_2>,
                mpl::plus<
                    mpl::_1, 
                    mpl::integral_c<unsigned long long, 1ull << getIndex<Set, mpl::_2>()>
                >,
                mpl::_1
            >
        >::type;
    return std::bitset<mpl::size<Set>::value>(type::value);
}

基本上,函数意图的要点是能够创建一个位集,其位基于SetPartialSet的交集创建,两者都是mpl::set s。还提供了函数getIndex

template <class Set, class Index>
constexpr auto getIndex() {
    return mpl::distance<
            typename mpl::begin<Set>::type,
            typename mpl::find<Set, Index>::type
        >::type::value;
}

这种方法似乎不起作用,编译错误评估如下:

'value' is not a member of 'boost::mpl::same_as<U1> in 'not.hpp'
'C_': invalid template argument for 'boost::mpl::aux::not_impl', expected compile-time constant expression in not.hpp

左移是否可能不是编译时常数?

问题似乎是调用getIndex,因为mpl::_2没有被替换。不幸的是,我无法弄清楚如何强制替换。

1 个答案:

答案 0 :(得分:1)

问题是您将place_holder传递给函数getIndex

你可以在结构中转换你的函数

template< typename Set, typename Index > struct getIndex
    : mpl::integral_c<unsigned long long, ( mpl::distance<
            typename mpl::begin<Set>::type,
            typename mpl::find<Set, Index>::type
        >::type::value )>
{
};

template <class Set, class PartialSet>
constexpr auto tupleBitset() {
    using type = 
        typename mpl::fold<
            PartialSet,
            mpl::integral_c<unsigned long long, 0>,
            mpl::eval_if<
                mpl::has_key<Set, mpl::_2>,
                mpl::plus<
                    mpl::_1, 
                    mpl::shift_left<mpl::integral_c<unsigned long long, 1ull>,
                                    getIndex<Set, mpl::_2>>
                >,
                mpl::_1
            >
        >::type;
    return std::bitset<mpl::size<Set>::value>(type::value);
}

Demo