У меня тут какая-то проблема.Я работаю над библиотекой рефлексии как комплектом упражнений и утилит для будущих проектов.Чтобы заставить его работать, я уже согласился с тем, что неизбежно быть навязчивым, и мне нужно будет добавить хотя бы небольшой кусочек кода в тело класса, чтобы получить ценные данные отражения.
Однако я бы хотелбудь здесь как можно более минималистичным.Итак, после изучения некоторых существующих реализаций я нашел подходящую мне концепцию.Для упрощения шаблон выглядит следующим образом:
class Base
{
int baseFoo;
double baseBar[5];
RTTINFO(baseFoo, baseBar);
};
(...)
Base sth;
std::cout << TypeInfo(sth).variables[0].name; << std::endl;
// I don't mind if the way of accessing the type info changes totally
Используя некоторое общее программирование, я могу в значительной степени скрыть все, что мне нравится, за этим RTTINFO
макросом и строением информационных структур типа.Я могу получить типы, имена, размер массива и т. Д. Но когда я хочу сделать еще один шаг и ввести наследование, например:
class Derived : public Base
{
std::string foo;
char* bar;
/* RTTIPARENT(Base); <-- I want to avoid this */
RTTINFO(foo, bar);
};
, тогда я бы хотел избежать указания Base и все еще иметь возможностьпопасть в RTTI своих членов.Я надеялся, что у Base
есть какой-то способ скрыть некоторые подсказки в его RTTINFO(...)
для Derived
, чтобы сделать это возможным.Итак ... есть ли?
Основные требования:
- Я не хочу указывать базовый класс нигде, кроме места, определенного языком.И я не хочу помещать
class Derived : public Base
в любой макрос. RTTIINFO
может добавить любой необходимый язык и смещение памяти для затронутого класса. - Я могу поместить все, что захочуМакрос
RTTINFO
, даже тонны кода, если необходимо. - И Base, и Derived используют один и тот же макрос
RTTINFO
, который, конечно, может быть повторно использован при дальнейшем наследовании.Оставим в стороне проблему множественного наследования, одиночное наследование кажется достаточно сложным. - Для
Derived
необязательно иметь доступ к RTTI Base
, это может быть любой другой внешний вспомогательный класс / функция, который будет обрабатыватьДанные RTTI.Однако частные переменные-члены должны поддерживаться. - Я не возражаю против затрат на компиляцию и время выполнения - если какие-либо вычисления, такие как построение дерева наследования, опрос всех существующих классов, что угодно, должны выполняться во время выполнения,всегда есть способ, с помощью которого я мог бы переместить его на этап инициализации программы, поэтому для меня это не имеет большого значения.
- Если возможно, избегайте RTTI с поддержкой языков, так как в некоторых проектах его нужно отключать.Во всяком случае, я не нашел решения даже с ним.
- Никакой дополнительный шаг компиляции не может быть добавлен.
Одно примечание: возможно, я мог бы использовать type_info::before()
, но даже если этобудет работать для обычных компиляторов, стандарт C ++ говорит, что я не могу здесь полагаться на отношения наследования.
Спасибо за любые предложения!
Andrew