尝试定义Boost :: mp11 :: find_if谓词失败

时间:2018-07-23 22:48:41

标签: c++ boost boost-mp11

我一直在写一些基于策略/特征的设计,但遇到了我不明白的Boost :: mp11问题。我已将问题简化为以下示例:

#include <iostream>
#include <variant>
#include <tuple>

#include <boost/hana/string.hpp>
#include <boost/mp11/algorithm.hpp>

using namespace boost::hana::literals;

struct stub_trait1
{
    static constexpr auto name = "stub_trait1"_s;
};

struct stub_trait2
{
    static constexpr auto name = "stub_trait2"_s;
};

struct test_card
{
    using traits_type = std::tuple<stub_trait1, stub_trait2>;

    explicit test_card() = default;
    traits_type traits;
};

using cards_t = std::variant<test_card>;

template <typename TraitName>
struct trait_name_predicate
{
    template <typename Trait>
    struct result : std::is_same<decltype(Trait::name), TraitName> {};
};

template <typename TraitName, typename Callable>
void generic_trait_processor(const cards_t& card, const Callable& f)
{
    std::visit([&](auto&& c) {
        using traits_type = typename std::decay_t<decltype(c)>::traits_type;
        using sr_idx = boost::mp11::mp_find_if<traits_type, trait_name_predicate<TraitName>::result>; // Fail!
        if constexpr (sr_idx::value != std::tuple_size_v<traits_type>) {
            auto& trait = std::get<sr_idx::value>(c.traits);
            f(c, trait);
        }
    },
    card);
}

int main()
{
    auto c = cards_t{test_card{}};
    generic_trait_processor<decltype("stub_trait1"_s)>(
        c,
        [](auto&& card, auto&& trait) {
            std::cout << "Trait: " << trait.name << std::endl;
        });

    return EXIT_SUCCESS;
}

您可以(尝试)运行代码here。编译器抱怨boost::mp11::find_if类型:

<source>: In lambda function:

<source>:42:100: error: type/value mismatch at argument 2 in template parameter list for 'template<class L, template<class ...> class P> using mp_find_if = typename boost::mp11::detail::mp_find_if_impl::type'

         using sr_idx = boost::mp11::mp_find_if<traits_type, trait_name_predicate<TraitName>::result>;

                                                                                                    ^

<source>:42:100: note:   expected a class template, got 'trait_name_predicate<TraitName>::result'

这两个错误都没有道理,参数2 是类型,trait_name_predicate<TraitName>::result 是类模板!

我和编译器彼此混淆-有人能看到我在做什么吗?

1 个答案:

答案 0 :(得分:0)

我需要告诉编译器,依赖名称result是模板:

using sr_idx = boost::mp11::mp_find_if<traits, trait_name_predicate<TraitName>::template result>;
                                                                                ^^^^