在命名空间上使用std::meta::members_of()

编程语言 2026-07-09

在首次尝试使用C++26反射时,我试图遍历一个命名空间中所有可用的成员。

为此,我首先用 std::meta::members_of 获取成员。

GCC 16.1表示我对 std::meta::members_of 的使用不是一个常量表达式。我到底做错了什么?

https://godbolt.org/z/sWP3h1nYo

#include <meta>
int main()
{
    constexpr auto ns_refl = ^^std;
    constexpr auto ctx = std::meta::access_context::unchecked();
    constexpr auto members = std::meta::members_of(ns_refl, ctx);

    // Then I would like to do:
    //template for (constexpr auto &member : members)
    //{
    //    std::cout << std::meta::identifier_of(member) << '\n';
    //}
}

来自GCC的错误:

<source>: In function 'int main()':
<source>:6:64: error: 'std::meta::members_of(((std::meta::info)ns_refl), ctx)' is not a constant expression because it refers to a result of 'operator new'
    6 |     constexpr auto members = std::meta::members_of(ns_refl, ctx);
      |                                                                ^
In file included from /cefs/38/383ad2f84cbd57a52fd68bbe_consolidated/compilers_c++_x86_gcc_16.1.0/include/c++/16.1.0/string:46,
                 from /cefs/38/383ad2f84cbd57a52fd68bbe_consolidated/compilers_c++_x86_gcc_16.1.0/include/c++/16.1.0/bits/stdexcept_throw.h:57,
                 from /cefs/38/383ad2f84cbd57a52fd68bbe_consolidated/compilers_c++_x86_gcc_16.1.0/include/c++/16.1.0/array:44,
                 from /cefs/38/383ad2f84cbd57a52fd68bbe_consolidated/compilers_c++_x86_gcc_16.1.0/include/c++/16.1.0/meta:42,
                 from <source>:1:
/cefs/38/383ad2f84cbd57a52fd68bbe_consolidated/compilers_c++_x86_gcc_16.1.0/include/c++/16.1.0/bits/allocator.h:203:52: note: allocated here
  203 |             return static_cast<_Tp*>(::operator new(__n));
      |                                      ~~~~~~~~~~~~~~^~~~~
ASM generation compiler returned: 1

解决方案

members_of 返回一个 std::vector。只要在常量表达式结束前被销毁,它就可以是常量表达式的一部分,但不能是整个常量表达式,因为它的元素不会被释放。

使用 std::define_static_array 来获得一个具有静态存储期限的数组,而不是指向动态存储期限元素的向量:

#include <meta>
#include <iostream> 

int main() {
    constexpr auto ns_refl = ^^std;
    constexpr auto ctx = std::meta::access_context::unchecked();
    constexpr auto members = std::define_static_array(std::meta::members_of(ns_refl, ctx));
    template for (constexpr auto& member : auto(members)) {
        if constexpr (std::meta::has_identifier(member))
            std::cout << std::meta::identifier_of(member) << '\n';
    }
}
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章