#c #template-meta-programming
#c #шаблон-мета-программирование
Вопрос:
Я пытаюсь создать библиотеку отражения C . Цель состоит в том, чтобы использовать анализатор clang для генерации набора метаданных из файлов заголовков для создания файлов заголовков meta, которые могут быть включены для выполнения определенных отражающих операций. Я использовал класс Meta_data, который становится специализированным для каждого типа в файле заголовка, и он довольно хорошо работает для конкретных типов, но не работает для вложенных структур внутри типов шаблонов.
Вот пример:
// header.h
struct foo
{
int member1;
int member2;
struct nested
{
int member;
};
};
template <int val>
struct template_foo
{
int member;
struct nested
{
int member;
};
};
// meta/header.h
#include <tuple>
#include <utility>
template <typename T>
struct Meta_data
{
static_assert(sizeof(T) != 0, "Must be specialized");
};
template <>
struct Meta_data<foo>
{
constexpr auto tuple_view(fooamp; object)
{
return std::forward_as_tuple(object.member1, object.member2);
}
};
template <>
struct Meta_data<foo::nested>
{
constexpr auto tuple_view(foo::nestedamp; object)
{
return std::forward_as_tuple(object.member);
}
};
template <int val>
struct Meta_data<template_foo<val>>
{
constexpr auto tuple_view(template_foo<val>amp; object)
{
return std::forward_as_tuple(object.member);
}
};
// This fails
//
// template <int val>
// struct Meta_data<typename template_foo<val>::nested>
// {
// constexpr auto tuple_view(template_foo<val>::nestedamp; object)
// {
// return std::forward_as_tuple(object.member);
// }
// };
//
//
// GCC 10.2.0 Error output
// test.cpp:56:8: error: template parameters not deducible in partial specialization:
// 56 | struct Meta_data<typename template_foo<val>::nested>
// | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// test.cpp:56:8: note: ‘val’
// test.cpp
int main()
{
}
Я понимаю ошибку компилятора, но я не могу придумать другого способа заставить это работать. Цель состоит в том, чтобы иметь возможность принимать любой тип и просматривать его члены как кортеж, например:
std::get<0>(Meta_data<some_struct>::tuple_view(some_struct_instance));
Есть ли способ перепроектировать мой Meta_class, чтобы я мог получить желаемое конечное поведение даже для вложенных структур в шаблонных структурах / классах?
Комментарии:
1. Подобные вещи предпринимались неудачно в течение десятилетий. Наиболее знакомый мне пример — это мета-объектный компилятор Qt. Обычно нет хорошего способа решить эту проблему без поддержки компилятора. Вот почему правильное отражение должно быть особенностью языка, и несколько умных людей C стремятся стандартизировать его.
2. Плагины компилятора довольно полезны для этого, и я лично пробовал их в прошлом. Это определенно работает, но для правильного выполнения требуется очень и очень много усилий.