Boost hana 获取字符串类型

Posted

技术标签:

【中文标题】Boost hana 获取字符串类型【英文标题】:Boost hana getting type in a string 【发布时间】:2018-02-04 11:35:00 【问题描述】:

我正在使用 boost::hana 来反映结构,并且我正在尝试获取成员的名称。我的工作解决方案使用 gcc 特定的宏,我想用更通用的东西替换它。

提供反射的头部看起来有点像这样

#include <boost/hana.hpp>
#include <string>
#include <iostream>

struct ReflectedStruct

    virtual void PrintMemberTypes() = 0;
    virtual ~ReflectedStruct()
;

template<class T> struct meta 
    static const std::string& get_name() return T::class_name;
;

#define TYPE_NAME(type) \
  template<>struct meta<type>  \
    static constexpr const char* class_name = #type; \
    static const char* get_name() return class_name; \
  ;

TYPE_NAME(double);

#define REFLECT_STRUCT(structure_name, ...)                                                         \
struct structure_name : ReflectedStruct                                                            \
  BOOST_HANA_DEFINE_STRUCT(structure_name, __VA_ARGS__ );                                           \
  void PrintMemberTypes()                                                                          \
      boost::hana::for_each(boost::hana::accessors<structure_name>(),                               \
                            [&](auto pair)                                                         \
                                std::cout                                                           \
                                  << meta< typeof( boost::hana::second(pair)(*this) ) >::get_name() \
                                  << std::endl;                                                     \
                                                                                                   \
                           );                                                                       \
                                                                                                   \
;                                                                                                  \
TYPE_NAME(structure_name);

使用它看起来像这样:

REFLECT_STRUCT(Runway,
  (double, lat),
  (double, lon),
  (double, hdg),
  (double, alt)
);

int main()

    Runway r;
    r.PrintMemberTypes();  // prints "double, double, double, double"
    return 0;

我的问题是如下所示的行:

meta< typeof( boost::hana::second(pair)(*this) ) >::get_name()

更具体地说,问题在于 gcc 特有的 typeof()。以下是我尝试过的一些事情:

// Ok, but gcc-specific.  Resolves to "double"
typeof   ( boost::hana::second(pair)(*this) ) 

// Error, is type "double&", I haven't specialized meta<> for that.
decltype ( boost::hana::second(pair)(*this) )

// error: Doesn't seem to resolve to a type
std::remove_reference<decltype( boost::hana::second(pair)(*this) )>::type

// error: Doesn't seem to resolve to a type
boost::hana::typeid_(boost::hana::second(pair)(*this))::type

我需要没有引用的类型。 我想另一种选择是将 meta&lt;&gt; 专门用于引用而不是类型本身。

【问题讨论】:

【参考方案1】:
// error: Doesn't seem to resolve to a type
std::remove_reference<decltype( boost::hana::second(pair)(*this) )>::type

由于pair的类型基本上是一个模板参数,type是一个依赖名,所以你需要使用typename

typename std::remove_reference<decltype( boost::hana::second(pair)(*this) )>::type

// error: Doesn't seem to resolve to a type
boost::hana::typeid_(boost::hana::second(pair)(*this))::type

你需要记住typeid_返回的是一个值,而不是一个类型,所以你不能直接在它的结果上使用::type。你需要使用decltype:

typename decltype(boost::hana::typeid_(boost::hana::second(pair)(*this)))::type

【讨论】:

你是对的。两种解决方案都有效。 typename 是我错过的重要内容。我会坚持使用你的 hana::typeid_ 解决方案,因为它可能会更好地处理我还没有想到的任何边缘情况。

以上是关于Boost hana 获取字符串类型的主要内容,如果未能解决你的问题,请参考以下文章

HANA:数据类型 BLOB 的数据库列中的未知字符

带有字符串键的矩阵是不是有 Boost(或其他常见库)类型?

boost::hana: 为啥我不能过滤一个集合?

Boost库简介

Boost库简介

如何将 boost::hana::tuple 转换为 std::variant