Comments 19
Ну, иногда compile time не обойтись. Как, например, по строковому имени (либо по идентификатору) создать объект класса, пользуясь compile time-рефлексией? А это нужно минимум для сериализации.
Фреймворки, заменяющие RTTI, используются как раз для того, чтобы получить предсказуемый RTTI только для некоторых классов, для которых нужен механизм RTTI (в отличие от стандартного RTTI).
Фреймворки, заменяющие RTTI, используются как раз для того, чтобы получить предсказуемый RTTI только для некоторых классов, для которых нужен механизм RTTI (в отличие от стандартного RTTI).
Конструировать статический std::map/unordered_map/concurrent_map/mysuper_map в удобном для задачи формате из compile-time информации ровно там, где это нужно.
cpprt не делает никакой магии в runtime. Принцип её работы следующий:
1. Выполнить регистрацию фабрик до старта main() за счёт вызова конструкторов этих же самых фабрик. Регистрация означает просто добавление в массив (считайте, в map).
2. Всё… Можно из этого массива через набор методов доставать информацию. Так же, как если бы был использован обычный массив (или map) фабрик, но обёрнутый в класс.
Это почти один-в-один похоже на все решения, которые тут предлагают с массивом фабрик и чуть медленнее решений, которые предлагаются со switch case (ведь вместо switch case будет обход мапы или массива).
Быстрее этого решения разве что решение, построенное на шаблонах, как это сделано с std::numeric_limits, где, фактически выполняется поиск нужной специализации шаблона. Тут я согласен, это будет быстрее, и я подумываю о том, как это можно встроить в библиотеку.
1. Выполнить регистрацию фабрик до старта main() за счёт вызова конструкторов этих же самых фабрик. Регистрация означает просто добавление в массив (считайте, в map).
2. Всё… Можно из этого массива через набор методов доставать информацию. Так же, как если бы был использован обычный массив (или map) фабрик, но обёрнутый в класс.
Это почти один-в-один похоже на все решения, которые тут предлагают с массивом фабрик и чуть медленнее решений, которые предлагаются со switch case (ведь вместо switch case будет обход мапы или массива).
Быстрее этого решения разве что решение, построенное на шаблонах, как это сделано с std::numeric_limits, где, фактически выполняется поиск нужной специализации шаблона. Тут я согласен, это будет быстрее, и я подумываю о том, как это можно встроить в библиотеку.
если устраивает сидеть только на clang'е
Почему? Можно ведь использовать libclang только для кодогенерации, а потом звать родной компилятор.
Как, например, по строковому имени (либо по идентификатору) создать объект класса, пользуясь compile time-рефлексией?
В простейшем варианте — при помощи switch/case или статического map<string,Factory>.
Так библиотека и хранит в себе что-то вроде map<string,Factory> (можете почитать первую статью о том, как это сделано). Библиотека просто даёт возможность через макросы описать нужную метаинформацию рядом с декларацией и реализацией классов.
Создание экземпляра класса вызовом factory, найденным по некоторому ключу в map, это не reflection. И для этого не нужны ни run-time, ни compile-time reflection.
В той же Java это относят к рефлексии, поэтому я тоже решил, что это можно назвать рефлексией. Я не претендую на большое количество предоставляемых метаданных, потому назвал статью «немного рефлексии для С++».
Нет, создание экземпляра класса при помощи factory не относится к reflection даже в Java. Это просто factory design pattern, который может использовать reflection, но в общем никак с ней не связан.
Ага… Ну хорошо, а получение информации об абстрактности классов или о их наследовании друг от друга?
Да. Инспекция, использование и модификация произвольных классов (даже неизвестных на момент компилирования) это reflection. Как и создание экземпляра класса таким способом (например, динамически нашли конструктор с нужной сигнатурой и вызвали его, подставив параметры).
Создание экземпляра класса через оператор new внутри factory (как и без factory) — нет.
Создание экземпляра класса через оператор new внутри factory (как и без factory) — нет.
Самая интересная фича в рефлексии это не получить имя класса, а получить список полей, их типы и офсеты. А создать фабрику типов можно и без рефлексии, с минимальным набором макросов.
Соглашусь. Тут есть некоторая терминологическая неточность. Я потому и назвал цикл «капелька рефлексии». По поводу списка полей и типов — этим занимается упоминаемая в статье «основная библиотека». Там используется обычное перечисление полей через вызовы методов save и load для объекты-сериализаторы. Я, увы, пока не довёл эту библиотеку до того вида, чтобы её можно было опубликовать.
Ну, в библиотеке и есть этот самый минимальный набор макросов.
А создать фабрику типов можно и без рефлексии, с минимальным набором макросов
Ну, в библиотеке и есть этот самый минимальный набор макросов.
Хорошо пишите. Рефлексия это хорошо… но двигаясь дальше вы все ближе подходите к необходимости второго .net (или java, кому как)?
Sign up to leave a comment.
Немного рефлексии для С++. Часть третья: документационная