Этот код статического отражения C ++ может автоматически получить число и имена переменных элементов в классе агрегата, с его основным процессом, разделенным на три шага: < /p>
1.at Время компиляции, вычислить общее количество переменных членов, «постепенно пытаясь построить агрегатный класс». < /p>
. Участники, используйте структурированную привязку, чтобы разложить его на ссылки на члены, а затем получить указатель для каждого члена.#include
#include
#include
#include
#include
#include
#include
template
struct reflect_member_handler {};
struct type_placeholder
{
template
operator E() const;
};
template
consteval static std::size_t aggregate_member_counter()
{
if constexpr( !requires{ T{ Args{}... }; } )
return sizeof...(Args) - 1;
else
return aggregate_member_counter();
}
template
consteval std::size_t get_member_count() {
return aggregate_member_counter();
}
template
std::string_view Iget_member_name()
{
static std::source_location location = std::source_location::current();
std::string_view func_name = location.function_name();
int first = func_name.find("::", func_name.find("(&")) + 2;
int last = func_name.find(")", first);
return func_name.substr(first, last - first);
}
#if 0
//----------------------- Part 1----------------------------
template
struct reflect_member_handler
{
static auto get_member_names()
{
static T object;
static auto& [v0] = object;
std::array names;
names[0] = Iget_member_name();
return names;
}
};
//----------------------------------------------------------
#else
//----------------------- Part 2----------------------------
template
struct reflect_member_handler
{
static auto get_member_names()
{
static std::byte memory[sizeof(T)];
static T& dummy_object = *reinterpret_cast(memory);
static auto& [v0] = dummy_object;
std::array names;
names[0] = Iget_member_name();
return names;
}
};
//----------------------------------------------------------
#endif
struct test_t { int a; };
int main()
{
auto member_names =
reflect_member_handler::get_member_names();
std::cout
gcc x86-64 15.2.0: < /p>
:35:18: warning: 'std::string_view Iget_member_name() [with auto E = (& v0)]' used but never defined
35 | std::string_view Iget_member_name()
| ^~~~~~~~~~~~~~~~
during RTL pass: expand
: In static member function 'static auto reflect_member_handler::get_member_names() [with T = test_t]':
:69:45: internal compiler error: Segmentation fault
69 | names[0] = Iget_member_name();
| ~~~~~~~~~~~~~~~~~~~~~^~
0x228dd45 diagnostic_context::diagnostic_impl(rich_location*, diagnostic_metadata const*, diagnostic_option_id, char const*, __va_list_tag (*) [1], diagnostic_t)
???:0
0x229f296 internal_error(char const*, ...)
???:0
0x13561cb make_decl_rtl(tree_node*)
???:0
0xaefebc expand_call(tree_node*, rtx_def*, int)
???:0
0xc1758e expand_expr_real_1(tree_node*, rtx_def*, machine_mode, expand_modifier, rtx_def**, bool)
???:0
0xc22c2e store_expr(tree_node*, rtx_def*, int, bool, bool)
???:0
Please submit a full bug report, with preprocessed source (by using -freport-bug).
Please include the complete backtrace with any bug report.
See for instructions.
Compiler returned: 1
< /code>
clang x86-64 20.1.0: < /p>
:69:24: error: no matching function for call to 'Iget_member_name'
69 | names[0] = Iget_member_name();
| ^~~~~~~~~~~~~~~~~~~~~
:80:69: note: in instantiation of member function 'reflect_member_handler::get_member_names' requested here
80 | reflect_member_handler::get_member_names();
| ^
:35:18: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'E'
35 | std::string_view Iget_member_name()
| ^
1 error generated.
Compiler returned: 1
< /code>
Эта проблема не является ошибкой, связанной с именованием. Как мне объяснить эту проблему?
Подробнее здесь: https://stackoverflow.com/questions/797 ... g-with-cla
Внутренняя ошибка компилятора (ICE) встречается с GCC, а компиляция с Clang также дает запутанные сообщения об ошибках ⇐ C++
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение