2016-12-04 51 views
1

documentation对于hana::keys说我可以在函数调用语法中使用它,例如hana::keys(s)其中s是符合概念hana::Struct的类的一个实例,它返回一系列关键对象。我可以在没有结构实例的情况下使用`hana :: keys`吗?

相关函数hana::accessors返回可用于从结构实例中获取相应成员的访问函数序列。

hana::accessorscan be used in two ways

hana::accessors(s) 
hana::accessors<S>() 

都是合法的,constexpr函数时S = decltype(s)返回同样的事情 - 序列对应于结构S

当我用hana::keys尝试此语法时,出现错误。下面是一个MCVE,适应于hana文件从一个例子:


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

namespace hana = boost::hana; 

struct Person { 
    BOOST_HANA_DEFINE_STRUCT(Person, 
     (std::string, name), 
     (unsigned short, age) 
    ); 
}; 


// Debug print a single structure 

template <typename T> 
void debug_print_field(const char * name, const T & value) { 
    std::cout << "\t" << name << ": " << value << std::endl; 
} 


template <typename S> 
void debug_print(const S & s) { 
    std::cout << "{\n"; 

    hana::for_each(hana::keys<S>(), [&s] (auto key) { 
    debug_print_field(hana::to<char const *>(key), hana::at_key(s, key)); 
    }); 

    std::cout << "}" << std::endl; 
} 

// Debug print compare two structures 

int main() { 
    Person john{"John", 30}, kevin{"Kevin", 20}; 

    debug_print(john); 
    std::cout << std::endl; 
    debug_print(kevin); 
    std::cout << std::endl; 
} 

$ g++-6 -std=c++14 -I/home/chris/boost/boost_1_61_0/ main.cpp 
main.cpp: In function ‘void debug_print(const S&)’: 
main.cpp:28:30: error: expected primary-expression before ‘>’ token 
    hana::for_each(hana::keys<S>(), [&s] (auto key) { 
          ^
main.cpp:28:32: error: expected primary-expression before ‘)’ token 
    hana::for_each(hana::keys<S>(), [&s] (auto key) { 
           ^

它,当我使用hana::keys(s)工作正常。

但在我的实际应用中,我没有结构的实例,它只是一个模板参数。

一劈,我做了这个:

// Work around for `hana::keys` 

template <typename S> 
constexpr decltype(auto) get_hana_keys() { 
    return decltype(hana::keys(std::declval<S>())){}; 
} 

相信这个作品基于我有限的实况描述hana实现细节的理解。 - hana::keys应该返回一个编译时字符串序列,并且所有信息都包含在该类型中,所以获取类型和默认构造它应该是等效的。

当我在我的MCVE中使用get_hana_keys<S>()时,它编译并运行正常。

但是我不知道它是否真的正确,或者我所做的假设超出了文档允许我假设的范围。

我正在使用增强版本1.61gcc 6.2.0

我想知道的是什么,

  • 是否有一个很好的理由,hana::keys<S>()不工作或者是这只是一个疏忽? hana似乎已经非常精心设计,所以我倾向于在这里猜测自己。

  • 我创建的破解或改进方法有什么问题吗?

回答

2

好问题!

hana::keys<S>()有没有很好的理由,或者这只是一个疏忽?

hana::keys<S>()不起作用的原因是在一般情况下无法实现它。实际上,keys最初设计为hana::map,其中密钥可能为为有状态,因此您确实需要一个对象才能返回有意义的对象。事实上,一个对象不需要检索hana::Struct的密钥,这只是一个巧合。

我创建的破解或改进方法有什么问题吗?

技术上,hana::string没有记录为默认构造的,所以默认情况下,这些建设的hana::tuple不能保证正常工作。但是,这是我在1eebdb中修复的一个疏忽,所以你很好。

话虽这么说,一个也许更地道的解决办法是以下几点:

template <typename S> 
constexpr auto get_hana_keys() { 
    return hana::transform(hana::accessors<S>(), hana::first); 
} 

其实,这就是我们如何界定hana::keyshana::Struct秒。

最后,请注意,所有与hana::Struct相关的东西都会更好地通过语言层面的反思,所以请原谅对Hana提供反思的古怪支持。在没有语言支持的情况下,在这方面做任何事情都很难。

相关问题