c++ boost pfr如何获取结构体字段的名称?

vs91vp4v  于 10个月前  发布在  其他
关注(0)|答案(1)|浏览(216)

在Boost 1.84(当前为in progress)中:
全新功能:字段名称反射。添加了新的constexpr boost::pfr::get_name<N,T>()函数,该函数返回一个std::string_view,其名称为聚合T的索引N处的字段。需要C++20。
使用latest version of pfr on github,您可以编写如下代码

#include <boost/pfr/core.hpp>
#include <boost/pfr/core_name.hpp>

struct S
{
    int i = 1;
    double d = 2;
    std::string s = "three";
};

const S s;
constexpr auto names = boost::pfr::names_as_array<S>();
boost::pfr::for_each_field(
    s,
    [&names](const auto& field, std::size_t idx)
    { std::cout << idx << ": " << names[idx] << " = " << field << '\n'; });

字符串
输出量:

0: i = 1
1: d = 2
2: s = three


这是如何工作的?这个blog post解释了聚合初始化是如何被重新利用来获取字段的,但是获取字段名看起来就像变魔术一样!但是我在三大编译器(最新的Visual C++、gcc 13.2和clang 16)上得到了上面的输出。我不知道在core_name20_static.hpp中看代码。

fslejnso

fslejnso1#

您可能熟悉boost::typeindex::type_id<T>().pretty_name()或各种自动“Enum to string”。这些使用__PRETTY_FUNCTION__/__FUNCSIG__来获取“美化”函数名(包括完整地写出模板参数)。使用此方法,我们可以获取模板参数的名称:

template<typename T>
void test() {
    std::cout << __PRETTY_FUNCTION__ << '\n';
}

template<auto V>
void test() {
    std::cout << __PRETTY_FUNCTION__ << '\n';
}

int main() {
    test<std::string>();
    enum { a };
    test<a>();
}

个字符
你会删除适当的字符,以获得你想要的“名称”。
在C20之前,指针/引用非类型模板参数必须指向完整的对象。在C20中,它们现在可以指向子对象。所以,您创建一个对象并指向它:

struct S
{
    int i = 1;
    double d = 2;
    std::string this_is_the_name_we_want = "three";
};

extern S fake_object;

template<auto* P>
void test() {
    std::cout << __PRETTY_FUNCTION__ << '\n';
}

int main() {
    test<&fake_object.this_is_the_name_we_want>();
}
// GCC output
void test() [with auto* P = (& fake_object.S::this_is_the_name_we_want)]

的字符串
(And使用与boost::pfr::for_each_field相同的方法获得对每个成员的引用)

相关问题