如何使用source_location::function_name获取数据成员名称

问题描述 投票:0回答:1

读完这个来源(以及我的答案)和这个来源后,我的印象是我们可以使用

std::source_location::function_name
来提取数据成员的名称。

假设我们有一些

struct_t
类型和
my_struct
实例。此外,以下属性对于
struct_t
有效:

  1. 非静态数据成员数量为3;
  2. 以下行编译成功并具有预期的结果 行为:
    auto& [a,b,c] = my_struct;
  3. 如果确实有必要,还有任何其他假设吗

Q:如何在没有其他库std::source_location::function_name

的情况下使用C++20
struct_t
中提取所有非静态数据成员名称?正确的答案应该很容易推广到任意数量的字段,并且与 g++、clang 和 MSVC 兼容。

下面的代码表明这个任务是很有可能的。但首先,它需要一个复制构造函数,并且与 MSVC 不兼容,这意味着它违反了 C++20 语言标准。您的答案可能会使用此代码作为起点,也可能根本不使用它

#include <iostream>
#include <type_traits>
#include <source_location>
#include <vector>
#include <string_view>
#include <array>    

struct struct_t {
    int field1;
    double field2;
    std::vector<int> field3;
};

template<void* p>
std::string_view get(){
      return std::source_location::current().function_name();
}

template<class T>
auto fields3(T&& st){
    static auto inst{std::forward<T>(st)};//bad. Needs a copy or move constructor 
    auto& [a,b,c]=inst;
    return std::array{get<(void*)&a>(), get<(void*)&b>(), get<(void*)&c>()};
}

int main()
{
    for (auto field:fields3(struct_t{})){
        std::cout<<field<<"\n";
    }
    //std::string_view get() [p = &inst.field1]
    //std::string_view get() [p = &inst.field2]
    //std::string_view get() [p = &inst.field3]
    return 0;
}
c++ reflection c++20 std-source-location
1个回答
1
投票

这里是链接库似乎采取的方法。基本策略似乎是将指针传递给已声明但从未定义的

static
成员对象的字段。因此,该对象从未被实际构造。不过,在这种非常特殊的情况下,访问此类对象的字段是可以的,所以是的,据我所知,这是符合标准的。

它是便携式的吗?不。这依赖于解析

std::source_location::current().function_name()
返回的字符串,该字符串是实现定义的,实际上可能包含也可能不包含传递给它的指针所指向的字段的名称。在 GCC 和 Clang 上确实如此;在 MSVC 上似乎没有。

© www.soinside.com 2019 - 2024. All rights reserved.