boost::hana::map 作为数据成员

boost::hana::map as a data member

我目前正在为个人项目学习 boost::hana

在下面的代码片段中,我创建了一个 boost::hana::map,将 type_c<T> 作为键,将 Foo<T> 的实例作为值。

它有效,但我真的很想使用 my_map 变量作为 class 成员 并且不可能使用 auto 成员声明中的限定符。此外,如果我能够以某种方式(作为模板参数或构造函数参数)传递 types 元组,那就太好了。

你有什么建议吗?

#include <iostream>
#include "boost/hana.hpp"
#include <typeinfo>

using namespace boost;

template<typename T>
class Foo {
    T t;    
public:    
    void print() { std::cout <<typeid(T).name() << t; }    
};

int main() {
    auto types = hana::tuple_t<float, int, std::string>;

    auto my_map = boost::hana::unpack(types, [](auto ...t) {
        return boost::hana::make_map(boost::hana::make_pair(t, Foo<typename decltype(t)::type>()) ...);
    });

    my_map[hana::type_c<int>].print();
}

问题是 lambda 不能在未计算的上下文中使用 (decltype)。

当然,自 c++14 以来,我们可以在任何自由函数上使用推导的 return 类型:

namespace detail {
    template <typename... T>
    static inline auto make_foo_map() {
        return boost::hana::unpack(hana::tuple_t<T...>, [](auto... t) {
                return boost::hana::make_map(boost::hana::make_pair(t, Foo<typename decltype(t)::type>())...);
            });
    }
}

template <typename... T>
using FooMap = decltype(detail::make_foo_map<T...>());

现在很简单:

FooMap<float, int, std::string> my_map;

现场演示

Live On Coliru

#include "boost/hana.hpp"
#include <iostream>
#include <typeinfo>

using namespace boost;

template <typename T> class Foo {
    T t;

  public:
    void print() { std::cout << typeid(T).name() << "t\n"; }
};

namespace detail {
    template <typename... T>
    static inline auto make_foo_map() {
        return boost::hana::unpack(hana::tuple_t<T...>, [](auto... t) {
                return boost::hana::make_map(boost::hana::make_pair(t, Foo<typename decltype(t)::type>())...);
            });
    }
}

template <typename... T>
using FooMap = decltype(detail::make_foo_map<T...>());

int main() {
    FooMap<float, int, std::string> my_map;

    my_map[hana::type_c<int>].print();
    my_map[hana::type_c<float>].print();
    my_map[hana::type_c<std::string>].print();
}