我可以在没有结构实例的情况下使用 `hana::keys` 吗?
Can I use `hana::keys` without an instance of the structure?
hana::keys
的 documentation 说我可以在函数调用语法中使用它,例如hana::keys(s)
其中 s
是满足概念 hana::Struct
的 class 的实例,它 return 是一系列关键对象。
一个相关函数,hana::accessors
,return是一系列访问函数,可用于从结构的实例中获取相应的成员。
hana::accessors
can be used in two ways:
hana::accessors(s)
hana::accessors<S>()
都是合法的,constexpr
函数return在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
应该是 return 一系列编译时字符串,所有信息都包含在类型中,所以只获取类型和默认构造它应该是等价的。
当我在我的 MCVE 中使用 get_hana_keys<S>()
时,它编译并运行良好。
但是我不知道它是否真的正确,或者我所做的假设是否超出了文档允许我假设的范围。
我正在使用增强版 1.61
和 gcc 6.2.0
。
我想知道的是,
hana::keys<S>()
不起作用是否有充分的理由,或者这只是一个疏忽? hana
好像设计的很用心,所以我有点怀疑自己了
我创建的 hack 有什么问题或改进方法吗?
好问题!
Is there a good reason that hana::keys<S>()
doesn't work or is this simply an oversight?
之所以hana::keys<S>()
不行,是因为一般情况下没有办法实现。事实上,keys
最初是为 hana::map
设计的,其中键 可以 是有状态的,因此您确实需要一个对象来 return 一些有意义的东西。一个对象不需要检索 hana::Struct
的键这一事实只是巧合。
Is there anything wrong with the hack I created or a way to improve it?
从技术上讲,hana::string
没有记录为可默认构造的,因此不能保证其中的 hana::tuple
默认构造有效。但是,这是我在 1eebdb 中修复的疏忽,所以你很好。
话虽这么说,也许更惯用的解决方案如下:
template <typename S>
constexpr auto get_hana_keys() {
return hana::transform(hana::accessors<S>(), hana::first);
}
事实上,这就是我们为 hana::Struct
定义 hana::keys
的方式。
最后,请注意,与 hana::Struct
相关的所有内容都将通过语言级反射得到更好的服务,因此请原谅 Hana 提供的对反射的古怪支持。没有语言支持,在那个领域真的很难做任何好事。
hana::keys
的 documentation 说我可以在函数调用语法中使用它,例如hana::keys(s)
其中 s
是满足概念 hana::Struct
的 class 的实例,它 return 是一系列关键对象。
一个相关函数,hana::accessors
,return是一系列访问函数,可用于从结构的实例中获取相应的成员。
hana::accessors
can be used in two ways:
hana::accessors(s)
hana::accessors<S>()
都是合法的,constexpr
函数return在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
应该是 return 一系列编译时字符串,所有信息都包含在类型中,所以只获取类型和默认构造它应该是等价的。
当我在我的 MCVE 中使用 get_hana_keys<S>()
时,它编译并运行良好。
但是我不知道它是否真的正确,或者我所做的假设是否超出了文档允许我假设的范围。
我正在使用增强版 1.61
和 gcc 6.2.0
。
我想知道的是,
hana::keys<S>()
不起作用是否有充分的理由,或者这只是一个疏忽?hana
好像设计的很用心,所以我有点怀疑自己了我创建的 hack 有什么问题或改进方法吗?
好问题!
Is there a good reason that
hana::keys<S>()
doesn't work or is this simply an oversight?
之所以hana::keys<S>()
不行,是因为一般情况下没有办法实现。事实上,keys
最初是为 hana::map
设计的,其中键 可以 是有状态的,因此您确实需要一个对象来 return 一些有意义的东西。一个对象不需要检索 hana::Struct
的键这一事实只是巧合。
Is there anything wrong with the hack I created or a way to improve it?
从技术上讲,hana::string
没有记录为可默认构造的,因此不能保证其中的 hana::tuple
默认构造有效。但是,这是我在 1eebdb 中修复的疏忽,所以你很好。
话虽这么说,也许更惯用的解决方案如下:
template <typename S>
constexpr auto get_hana_keys() {
return hana::transform(hana::accessors<S>(), hana::first);
}
事实上,这就是我们为 hana::Struct
定义 hana::keys
的方式。
最后,请注意,与 hana::Struct
相关的所有内容都将通过语言级反射得到更好的服务,因此请原谅 Hana 提供的对反射的古怪支持。没有语言支持,在那个领域真的很难做任何好事。