是否可以对使用 Boost Hana 的方法进行内省?
Is it possible to introspect on methods using Boost Hana?
Boost Hana 提供了以简单而美观的方式对 class 成员字段进行内省的能力:
// define:
struct Person {
std::string name;
int age;
};
// below could be done inline, but I prefer not polluting the
// declaration of the struct
BOOST_HANA_ADAPT_STRUCT(not_my_namespace::Person, name, age);
// then:
Person john{"John", 30};
hana::for_each(john, [](auto pair) {
std::cout << hana::to<char const*>(hana::first(pair)) << ": "
<< hana::second(pair) << std::endl;
});
但是,文档只提到了成员字段。我也想反省方法。我试图用一种方法天真地扩展这个例子:
struct Foo {
std::string get_name() const { return "louis"; }
};
BOOST_HANA_ADAPT_STRUCT(::Foo, get_name);
编译通过。但是,一旦我尝试使用它,使用类似于上面的代码 (for_each
...),我就会遇到很多编译错误。由于没有显示方法自省的示例,我想知道是否支持它。
我原来的回答是废话;对不起。这是实际回答问题的重写。
我刚刚添加了一个宏,以便使用自定义访问器轻松定义 Struct
。方法如下:
#include <boost/hana/adapt_adt.hpp>
#include <boost/hana/at_key.hpp>
#include <boost/hana/string.hpp>
#include <cassert>
#include <string>
namespace hana = boost::hana;
struct Person {
Person(std::string const& name, int age) : name_(name), age_(age) { }
std::string const& get_name() const { return name_; }
int get_age() const { return age_; }
private:
std::string name_;
int age_;
};
BOOST_HANA_ADAPT_ADT(Person,
(name, [](auto const& p) { return p.get_name(); }),
(age, [](auto const& p) { return p.get_age(); })
);
int main() {
Person bob{"Bob", 30};
assert(hana::at_key(bob, BOOST_HANA_STRING("name")) == "Bob");
assert(hana::at_key(bob, BOOST_HANA_STRING("age")) == 30);
}
该代码应该适用于 master
。否则,如果您需要更多地控制访问器的定义或用于映射到访问器的键,您也可以手动定义整个事物:
namespace boost { namespace hana {
template <>
struct accessors_impl<Person> {
static auto apply() {
return hana::make_tuple(
hana::make_pair(BOOST_HANA_STRING("name"), [](auto&& p) -> std::string const& {
return p.get_name();
}),
hana::make_pair(BOOST_HANA_STRING("age"), [](auto&& p) {
return p.get_age();
})
);
}
};
}}
您可以在 Struct
概念的 reference 中找到有关如何定义 Struct
的更多信息。
Boost Hana 提供了以简单而美观的方式对 class 成员字段进行内省的能力:
// define:
struct Person {
std::string name;
int age;
};
// below could be done inline, but I prefer not polluting the
// declaration of the struct
BOOST_HANA_ADAPT_STRUCT(not_my_namespace::Person, name, age);
// then:
Person john{"John", 30};
hana::for_each(john, [](auto pair) {
std::cout << hana::to<char const*>(hana::first(pair)) << ": "
<< hana::second(pair) << std::endl;
});
但是,文档只提到了成员字段。我也想反省方法。我试图用一种方法天真地扩展这个例子:
struct Foo {
std::string get_name() const { return "louis"; }
};
BOOST_HANA_ADAPT_STRUCT(::Foo, get_name);
编译通过。但是,一旦我尝试使用它,使用类似于上面的代码 (for_each
...),我就会遇到很多编译错误。由于没有显示方法自省的示例,我想知道是否支持它。
我原来的回答是废话;对不起。这是实际回答问题的重写。
我刚刚添加了一个宏,以便使用自定义访问器轻松定义 Struct
。方法如下:
#include <boost/hana/adapt_adt.hpp>
#include <boost/hana/at_key.hpp>
#include <boost/hana/string.hpp>
#include <cassert>
#include <string>
namespace hana = boost::hana;
struct Person {
Person(std::string const& name, int age) : name_(name), age_(age) { }
std::string const& get_name() const { return name_; }
int get_age() const { return age_; }
private:
std::string name_;
int age_;
};
BOOST_HANA_ADAPT_ADT(Person,
(name, [](auto const& p) { return p.get_name(); }),
(age, [](auto const& p) { return p.get_age(); })
);
int main() {
Person bob{"Bob", 30};
assert(hana::at_key(bob, BOOST_HANA_STRING("name")) == "Bob");
assert(hana::at_key(bob, BOOST_HANA_STRING("age")) == 30);
}
该代码应该适用于 master
。否则,如果您需要更多地控制访问器的定义或用于映射到访问器的键,您也可以手动定义整个事物:
namespace boost { namespace hana {
template <>
struct accessors_impl<Person> {
static auto apply() {
return hana::make_tuple(
hana::make_pair(BOOST_HANA_STRING("name"), [](auto&& p) -> std::string const& {
return p.get_name();
}),
hana::make_pair(BOOST_HANA_STRING("age"), [](auto&& p) {
return p.get_age();
})
);
}
};
}}
您可以在 Struct
概念的 reference 中找到有关如何定义 Struct
的更多信息。