Я хотел бы иметь возможность проанализировать класс C ++ на предмет его имени, содержимого (т.е. членов и их типов) и т. Д. Я говорю здесь на родном C ++, а не на управляемом C ++, в котором есть отражение. Я понимаю, что C ++ предоставляет некоторую ограниченную информацию, используя RTTI. Какие дополнительные библиотеки (или другие методы) могут предоставить эту информацию?
263
Ответы:
Вам нужно, чтобы препроцессор генерировал данные отражения о полях. Эти данные могут быть сохранены как вложенные классы.
Во-первых, чтобы было проще и понятнее записать его в препроцессоре, мы будем использовать типизированное выражение. Типизированное выражение - это просто выражение, которое помещает тип в круглые скобки. Поэтому вместо того, чтобы писать,
int x
вы будете писать(int) x
. Вот несколько полезных макросов, которые помогут с типизированными выражениями:Далее мы определяем
REFLECTABLE
макрос для генерации данных о каждом поле (плюс само поле). Этот макрос будет называться так:Таким образом, используя Boost.PP, мы перебираем каждый аргумент и генерируем данные следующим образом:
Это генерирует константу,
fields_n
которая является числом отражаемых полей в классе. Затем он специализируетсяfield_data
для каждого поля. Он также дружит сreflector
классом, так что он может получить доступ к полям, даже если они закрыты:Теперь, чтобы перебрать поля, мы используем шаблон посетителя. Мы создаем диапазон MPL от 0 до количества полей и получаем доступ к данным поля по этому индексу. Затем он передает данные поля предоставленному пользователем посетителю:
Теперь для момента истины мы собрали все это вместе. Вот как мы можем определить
Person
класс, который является отражаемым:Вот обобщенная
print_fields
функция, использующая данные отражения для перебора полей:Пример использования
print_fields
с отражаемымPerson
классом:Какие выводы:
И вуаля, мы только что реализовали отражение в C ++, менее чем в 100 строках кода.
источник
#define DETAIL_TYPEOF_INT2(tuple) DETAIL_TYPEOF_HEAD tuple
и#define DETAIL_TYPEOF_INT(...) DETAIL_TYPEOF_INT2((__VA_ARGS__))
и изменить определение TYPEOF (x) на:#define TYPEOF(x) DETAIL_TYPEOF_INT(DETAIL_TYPEOF_PROBE x,)
Есть два вида
reflection
плавания.Это невозможно с C ++.
Такое возможно с использованием C ++
template-tricks
. Используйтеboost::type_traits
для многих вещей (например, проверка, является ли тип целым). Для проверки существования функции-члена используйте Можно ли написать шаблон для проверки существования функции? , Для проверки, существует ли определенный вложенный тип, используйте простой SFINAE .Если вы скорее ищете способы выполнения 1), например, посмотрите, сколько методов у класса, или хотите получить строковое представление идентификатора класса, то я боюсь, что нет стандартного C ++ способа сделать это. Вы должны использовать либо
C ++ сделан с учетом скорости. Если вы хотите высокоуровневую проверку, как в C # или Java, то, боюсь, я должен сказать вам, что без некоторых усилий нет пути.
источник
members<T>
которая возвращает список всех членов T. Если бы мы хотели иметь отражение во время выполнения (т.е. RTTI, смешанное с отражением), компилятор все равно будет знать все отраженные базовые типы. Вполне вероятно,members<T>(T&)
что никогда не будет создан экземпляр для T = std :: string, поэтому нет необходимости включать RTTI для std :: string или его производных классов.И я бы хотел пони, но пони не бесплатны. :-п
http://en.wikibooks.org/wiki/C%2B%2B_Programming/RTTI - это то, что вы собираетесь получить. Отражение, о котором вы думаете, - полностью описательные метаданные, доступные во время выполнения, - просто не существует для C ++ по умолчанию.
источник
Информация существует - но не в том формате, который вам нужен, и только если вы экспортируете свои классы. Это работает в Windows, я не знаю о других платформах. Используя спецификаторы класса хранилища, как, например:
Это заставляет компилятор встраивать данные определения класса в DLL / Exe. Но это не в формате, который вы можете легко использовать для размышлений.
В моей компании мы создали библиотеку, которая интерпретирует эти метаданные и позволяет вам отражать класс, не вставляя дополнительные макросы и т. Д. В сам класс. Это позволяет вызывать функции следующим образом:
Это эффективно делает:
Функция Invoke (this_pointer, ...) имеет переменные аргументы. Очевидно, что вызывая функцию таким образом, вы обходите такие вещи, как const-safety и т. Д., Поэтому эти аспекты реализуются как проверки во время выполнения.
Я уверен, что синтаксис может быть улучшен, и он пока работает только на Win32 и Win64. Мы обнаружили, что это действительно полезно, если у вас есть автоматические графические интерфейсы для классов, создание свойств в C ++, потоковая передача в и из XML и т. Д., И нет необходимости выводить из определенного базового класса. Если есть достаточно спроса, возможно, мы могли бы привести его в форму для выпуска.
источник
__declspec(dllexport)
и вы можете получить информацию из файла .map, если вы разрешите создание такого во время сборки.Отражение не поддерживается C ++ из коробки. Это печально, потому что это делает оборонительные испытания болью.
Есть несколько подходов к рефлексии:
Первая ссылка выглядит наиболее многообещающе (использует мод для лязга), вторая обсуждает ряд приемов, третья - это другой подход с использованием gcc:
http://www.donw.org/rfl/
https://bitbucket.org/dwilliamson/clreflect
https://root.cern.ch/how/how-use-reflex
В настоящее время существует рабочая группа для отражения C ++. Смотрите новости для C ++ 14 @ CERN:
Изменить 13/08/17:
Начиная с оригинального поста было много потенциальных улучшений в рефлексии. Ниже приводится более подробная информация и обсуждение различных методов и статуса:
Однако он не выглядит многообещающим в отношении стандартизированного подхода к отражению в C ++ в ближайшем будущем, если сообщество не проявит гораздо больше интереса к поддержке отражения в C ++.
Ниже приведена подробная информация о текущем состоянии на основе отзывов с последнего совещания по стандартам C ++:
Изменить 13/12/2017
Отражение, похоже, движется к C ++ 20 или, более вероятно, к TSR. Движение однако медленное.
Изменить 15/09/2018
Проект ТС был разослан в национальные органы для голосования.
Текст можно найти здесь: https://github.com/cplusplus/reflection-ts
Изменить 11/07/2019
Отражение TS полностью готово и доступно для комментариев и голосования в течение лета (2019).
Подход мета-шаблонного программирования должен быть заменен более простым подходом временного кода компиляции (не отраженным в TS).
Изменить 10/02/2020
Здесь есть запрос на поддержку TS отражения в Visual Studio:
Поговорим на TS автора Дэвида Санкеля:
http://cppnow.org/history/2019/talks/
https://www.youtube.com/watch?v=VMuML6vLSus&feature=youtu.be
Изменить 17 марта 2020 г.
Прогресс на размышление делается. Отчет «Отчет о поездке комитета ISO C ++ 2020-02 в Праге» можно найти здесь:
Подробности о том, что рассматривается для C ++ 23, можно найти здесь (включает короткий раздел по Reflection):
Изменить 4 июня 2020 года
Джефф Прешинг выпустил новый фреймворк под названием «Фанера», который содержит механизм для отражения во время выполнения. Более подробную информацию можно найти здесь:
Инструменты и подход выглядят наиболее полными и простыми в использовании.
источник
Вам нужно посмотреть, что вы пытаетесь сделать, и будет ли RTTI удовлетворять вашим требованиям. Я реализовал свое собственное псевдоотражение для некоторых очень специфических целей. Например, я однажды хотел иметь возможность гибко настраивать то, что будет выводить симуляция. Это потребовало добавления некоторого стандартного кода к классам, которые будут выводиться:
Первый вызов добавляет этот объект в систему фильтрации, которая вызывает
BuildMap()
метод, чтобы выяснить, какие методы доступны.Затем в файле конфигурации вы можете сделать что-то вроде этого:
С помощью некоторого волшебства шаблона
boost
это преобразуется в серию вызовов методов во время выполнения (когда читается файл конфигурации), так что это довольно эффективно. Я бы не рекомендовал делать это, если вам действительно не нужно, но, когда вы это делаете, вы можете делать действительно классные вещи.источник
Я бы порекомендовал использовать Qt .
Существует лицензия с открытым исходным кодом, а также коммерческая лицензия.
источник
Что вы пытаетесь сделать с отражением?
Вы можете использовать черты типа Boost и библиотеки typeof как ограниченную форму отражения во время компиляции. То есть вы можете проверять и изменять основные свойства типа, передаваемого в шаблон.
источник
РЕДАКТИРОВАТЬ : CAMP больше не поддерживается; доступны две вилки:
CAMP - это лицензированная библиотека MIT (ранее LGPL), которая добавляет отражение в язык C ++. Это не требует определенного шага предварительной обработки при компиляции, но привязка должна быть сделана вручную.
Текущая библиотека Tegesoft использует Boost, но есть также форк, использующий C ++ 11, который больше не требует Boost .
источник
Однажды я сделал что-то вроде того, что вам нужно, и хотя возможно получить некоторый уровень отражения и доступа к функциям более высокого уровня, головная боль от обслуживания может не стоить того. Моя система использовалась для полного отделения классов пользовательского интерфейса от бизнес-логики путем делегирования, схожего с концепцией Objective-C передачи и пересылки сообщений. Способ сделать это - создать некоторый базовый класс, способный отображать символы (я использовал пул строк, но вы могли бы сделать это с помощью перечислений, если вы предпочитаете скорость обработки ошибок во время компиляции, а не полную гибкость) функциям-указателям (на самом деле это не так). просто указатели на функции, но что-то похожее на то, что есть в Boost с Boost.Function - к которому у меня не было доступа в то время). Вы можете сделать то же самое для переменных-членов, если у вас есть некоторый общий базовый класс, способный представлять любое значение. Вся система была безошибочным грабежом кодирования и делегирования ключей, с несколькими побочными эффектами, которые, возможно, стоили огромного количества времени, необходимого для того, чтобы каждый класс, использующий систему, соответствовал всем своим методам и элементам законным вызовам. : 1) Любой класс может вызывать любой метод любого другого класса без необходимости включать заголовки или писать поддельные базовые классы, чтобы интерфейс мог быть предопределен для компилятора; и 2) геттеры и сеттеры переменных-членов было легко сделать потокобезопасными, потому что изменение или доступ к их значениям всегда делался с помощью 2 методов в базовом классе всех объектов. Вся система была безошибочным грабежом кодирования и делегирования ключей, с несколькими побочными эффектами, которые, возможно, стоили огромного количества времени, необходимого для того, чтобы каждый класс, использующий систему, соответствовал всем своим методам и элементам законным вызовам. : 1) Любой класс может вызывать любой метод любого другого класса без необходимости включать заголовки или писать поддельные базовые классы, чтобы интерфейс мог быть предопределен для компилятора; и 2) геттеры и сеттеры переменных-членов было легко сделать потокобезопасными, потому что изменение или доступ к их значениям всегда делался с помощью 2 методов в базовом классе всех объектов. Вся система была безошибочным грабежом кодирования и делегирования ключей, с несколькими побочными эффектами, которые, возможно, стоили огромного количества времени, необходимого для того, чтобы каждый класс, использующий систему, соответствовал всем своим методам и элементам законным вызовам. : 1) Любой класс может вызывать любой метод любого другого класса без необходимости включать заголовки или писать поддельные базовые классы, чтобы интерфейс мог быть предопределен для компилятора; и 2) геттеры и сеттеры переменных-членов было легко сделать потокобезопасными, потому что изменение или доступ к их значениям всегда делался с помощью 2 методов в базовом классе всех объектов. 1) Любой класс может вызывать любой метод любого другого класса без необходимости включать заголовки или писать поддельные базовые классы, чтобы интерфейс мог быть предопределен для компилятора; и 2) геттеры и сеттеры переменных-членов было легко сделать потокобезопасными, потому что изменение или доступ к их значениям всегда делался с помощью 2 методов в базовом классе всех объектов. 1) Любой класс может вызывать любой метод любого другого класса без необходимости включать заголовки или писать поддельные базовые классы, чтобы интерфейс мог быть предопределен для компилятора; и 2) геттеры и сеттеры переменных-членов было легко сделать потокобезопасными, потому что изменение или доступ к их значениям всегда делался с помощью 2 методов в базовом классе всех объектов.
Это также привело к возможности делать действительно странные вещи, которые в C ++ были бы непростыми. Например, я мог бы создать объект Array, который содержал произвольные элементы любого типа, включая самого себя, и динамически создавать новые массивы, передавая сообщение всем элементам массива и собирая возвращаемые значения (аналогично map в Lisp). Другой была реализация наблюдения значения ключа, благодаря которой я смог настроить пользовательский интерфейс для немедленного реагирования на изменения в членах внутренних классов вместо того, чтобы постоянно опрашивать данные или излишне перерисовывать отображение.
Возможно, более интересным для вас является тот факт, что вы также можете сбросить все методы и члены, определенные для класса, и в виде строки не меньше.
Недостатки системы, которые могут отговорить вас от беспокойства: добавление всех сообщений и значений ключей чрезвычайно утомительно; это медленнее, чем без каких-либо размышлений; ты будешь ненавидеть видеть
boost::static_pointer_cast
иboost::dynamic_pointer_cast
повсюду вашу кодовую базу с сильной страстью; ограничения строго типизированной системы все еще существуют, вы просто их немного скрываете, поэтому это не так очевидно. Опечатки в ваших строках также не являются забавным или легко обнаруживаемым сюрпризом.Что касается того, как реализовать что-то вроде этого: просто используйте общие и слабые указатели на какую-то общую базу (мой был очень образно назван «Объект») и извлекайте для всех типов, которые вы хотите использовать. Я бы порекомендовал установить Boost.Function вместо того, чтобы делать это так, как я делал, что было с какой-то нестандартной хренью и кучей уродливых макросов, чтобы обернуть вызовы указателя функции. Поскольку все сопоставлено, проверка объектов - это просто итерация по всем ключам. Поскольку мои классы были практически максимально приближены к прямому грабежу Какао с использованием только C ++, если вы хотите что-то подобное, я бы предложил использовать документацию по Какао в качестве образца.
источник
В C ++ есть еще одна новая библиотека для отражения, называемая RTTR (Run Time Type Reflection, см. Также github ).
Интерфейс похож на отражение в C # и работает без каких-либо RTTI.
источник
Два похожих на рефлексию решения, которые я знаю по моим дням в C ++:
1) Используйте RTTI, который обеспечит вам начальную загрузку для построения вашего поведения, похожего на отражение, если вы сможете получить все свои классы из базового класса «объект». Этот класс может предоставлять некоторые методы, такие как GetMethod, GetBaseClass и т. Д. Что касается работы этих методов, вам нужно будет вручную добавить несколько макросов для украшения ваших типов, которые за кулисами создают метаданные в типе, чтобы предоставить ответы на GetMethods и т. Д.
2) Другой вариант, если у вас есть доступ к объектам компилятора, это использовать DIA SDK . Если я правильно помню, это позволяет вам открывать pdbs, которая должна содержать метаданные для ваших типов C ++. Этого может быть достаточно, чтобы сделать то, что вам нужно. На этой странице показано, как вы можете получить все базовые типы класса, например.
Оба эти решения немного уродливы, хотя! Нет ничего лучше, чем немного C ++, чтобы вы могли оценить роскошь C #.
Удачи.
источник
РЕДАКТИРОВАТЬ: Обновленная неработающая ссылка по состоянию на 7 февраля 2017 года.
Я думаю, что никто не упомянул это:
В CERN они используют систему полного отражения для C ++:
ЦЕРН Рефлекс . Кажется, работает очень хорошо.
источник
Этот вопрос сейчас немного стар (не знаю, почему я продолжаю задавать старые вопросы сегодня), но я думал о BOOST_FUSION_ADAPT_STRUCT, который вводит отражение во время компиляции.
Конечно, вы должны отобразить это на отражение во время выполнения, и это будет не слишком легко, но это возможно в этом направлении, хотя это не будет наоборот :)
Я действительно думаю, что макрос для инкапсуляции
BOOST_FUSION_ADAPT_STRUCT
может генерировать необходимые методы для получения поведения во время выполнения.источник
Я думаю, что вы могли бы найти интересную статью Доминика Филиона "Использование шаблонов для отражения в C ++". Он находится в разделе 1.4 игры Gems 5 . К сожалению, у меня нет своей копии со мной, но ищите ее, потому что я думаю, что это объясняет то, что вы просите.
источник
Вдумайтесь - это библиотека отражений C ++, в ответ на этот вопрос. Я рассмотрел варианты и решил сделать свои собственные, так как я не мог найти тот, который отмечал бы все мои коробки.
Хотя на этот вопрос есть отличные ответы, я не хочу использовать тонны макросов или полагаться на Boost. Boost - отличная библиотека, но есть множество небольших проектов C ++ 0x, которые проще и быстрее компилируются. Существуют также преимущества возможности внешнего декорирования класса, например, оборачивание библиотеки C ++, которая (пока?) Не поддерживает C ++ 11. Это форк CAMP, использующий C ++ 11, который больше не требует Boost .
источник
Отражение - это, по сути, то, что компилятор решил оставить как следы в коде, который может запросить код времени выполнения. C ++ славится тем, что не платит за то, что вы не используете; Поскольку большинство людей не используют / не хотят отражения, компилятор C ++ избегает затрат, ничего не записывая .
Таким образом, C ++ не дает отражения, и его не так просто «смоделировать» как общее правило, как отмечали другие ответы.
В разделе «другие методы», если у вас нет языка с отражением, получите инструмент, который может извлекать нужную вам информацию во время компиляции.
Наш инструментарий реинжиниринга программного обеспечения DMS представляет собой обобщенную технологию компиляции, параметризованную явными определениями языка. У этого есть определения языка для C, C ++, Java, COBOL, PHP, ...
Для версий C, C ++, Java и COBOL он обеспечивает полный доступ к деревьям разбора и информации таблицы символов. Эта информация таблицы символов включает в себя тип данных, которые вы, вероятно, захотите получить от «отражения». Если ваша цель состоит в том, чтобы перечислить некоторый набор полей или методов и что- то с ними сделать, DMS можно использовать для преобразования кода в соответствии с тем, что вы найдете в таблицах символов произвольным образом.
источник
Вы можете найти другую библиотеку здесь: http://www.garret.ru/cppreflection/docs/reflect.html. Она поддерживает 2 способа: получение информации о типе из отладочной информации и позволить программисту предоставить эту информацию.
Я также заинтересовался размышлениями для своего проекта и нашел эту библиотеку, я еще не пробовал ее, но попробовал другие инструменты этого парня, и мне нравится, как они работают :-)
источник
Проверьте Classdesc http://classdesc.sf.net . Он обеспечивает отражение в форме «дескрипторов» класса, работает с любым стандартным компилятором C ++ (да, известно, что он работает как с Visual Studio, так и с GCC) и не требует аннотации исходного кода (хотя существуют некоторые прагмы для обработки сложных ситуаций. ). Он разрабатывался более десяти лет и использовался в ряде проектов промышленного масштаба.
источник
Когда я хотел отражения в C ++, я читал эту статью и улучшил то, что увидел там. Извините, не могу. Я не владею результатом ... но вы, конечно, можете получить то, что у меня было, и пойти оттуда.
В настоящее время я исследую, когда мне так хочется, методы, которые можно использовать для использования attribute_linearly, чтобы упростить определение отражаемых типов. Я довольно далеко продвинулся в этом деле, но у меня все еще есть пути. Изменения в C ++ 0x, скорее всего, окажут большую помощь в этой области.
источник
Похоже, C ++ до сих пор не имеет этой функции. И C ++ 11 тоже отложил отражение ((
Ищите некоторые макросы или делайте собственные. Qt также может помочь с отражением (если это можно использовать).
источник
даже если в c ++ отражение не поддерживается "из коробки", его не сложно реализовать. Я встречал эту замечательную статью: http://replicaisland.blogspot.co.il/2010/11/building-reflective-object-system-in-c.html
В статье подробно объясняется, как можно реализовать довольно простую и элементарную систему отражения. предоставил его не самое полезное решение, и есть еще острые края, которые нужно разобраться, но для моих нужд этого было достаточно.
Нижняя строка - отражение может окупиться, если все сделано правильно, и это полностью выполнимо в C ++.
источник
Я хотел бы рекламировать существование автоматического инструментария самоанализа / отражения "IDK". Он использует мета-компилятор, такой как Qt, и добавляет метаинформацию непосредственно в объектные файлы. Утверждается, что он прост в использовании. Нет внешних зависимостей. Он даже позволяет автоматически отражать std :: string и затем использовать его в скриптах. Пожалуйста, посмотрите на ИДК
источник
Если вы ищете относительно простое отражение C ++ - я собрал из различных источников макро / определения и прокомментировал их, как они работают. Вы можете скачать заголовочные файлы здесь:
https://github.com/tapika/TestCppReflect/blob/master/MacroHelpers.h
набор определений плюс функциональность поверх него:
https://github.com/tapika/TestCppReflect/blob/master/CppReflect.h https://github.com/tapika/TestCppReflect/blob/master/CppReflect.cpp https://github.com/tapika/TestCppReflect/ блоб / ведущий / TypeTraits.h
Пример приложения также находится в репозитории git, здесь: https://github.com/tapika/TestCppReflect/
Я частично скопирую это здесь с объяснением:
REFLECTABLE
define использует имя класса + имя поля сoffsetof
-, чтобы определить, в каком месте в памяти находится конкретное поле. Я постарался максимально приблизиться к терминологии .NET, но C ++ и C # различны, так что это не 1 к 1. Вся модель отражения C ++ находится в классахTypeInfo
иFieldInfo
классах.Я использовал pugi xml parser для извлечения демонстрационного кода в xml и восстановления его из xml.
Таким образом, вывод, созданный демонстрационным кодом, выглядит следующим образом:
Также возможно включить любую поддержку класса / структуры третьей стороны через класс TypeTraits и частичную спецификацию шаблона - чтобы определить свой собственный класс TypeTraitsT, аналогично CString или int - см. Пример кода в
https://github.com/tapika/TestCppReflect/blob/master/TypeTraits.h#L195
Это решение применимо для Windows / Visual Studio. Можно портировать его на другие ОС / компиляторы, но этого еще не сделали. (Спросите меня, если вам действительно нравится решение, я мог бы помочь вам)
Это решение применимо для сериализации одним выстрелом одного класса с несколькими подклассами.
Однако, если вы ищете механизм для сериализации частей класса или даже для контроля над тем, что производят вызовы отражения, вы можете взглянуть на следующее решение:
https://github.com/tapika/cppscriptcore/tree/master/SolutionProjectModel
Более подробную информацию можно найти в видео YouTube:
Отражение типа среды выполнения C ++ https://youtu.be/TN8tJijkeFE
Я пытаюсь объяснить немного глубже о том, как будет работать отражение С ++.
Пример кода будет выглядеть, например, так:
https://github.com/tapika/cppscriptcore/blob/master/SolutionProjectModel/testCppApp.cpp
Но каждый шаг здесь фактически приводит к вызову функции с использованием свойств C ++ с
__declspec(property(get =, put ... )
.который получает полную информацию о типах данных C ++, именах свойств C ++ и указателях экземпляров классов в форме пути, и на основе этой информации вы можете генерировать xml, json или даже сериализовать эту информацию через Интернет.
Примеры таких виртуальных функций обратного вызова можно найти здесь:
https://github.com/tapika/cppscriptcore/blob/master/SolutionProjectModel/VCConfiguration.cpp
Смотрите функции
ReflectCopy
и виртуальные функции::OnAfterSetProperty
.Но поскольку тема действительно продвинутая - рекомендую сначала проверить видео.
Если у вас есть идеи по улучшению, не стесняйтесь связаться со мной.
источник
Библиотека отражений произвольного доступа обеспечивает довольно простое и интуитивно понятное отражение - вся информация о полях / типах предназначена для того, чтобы либо быть доступной в массивах, либо ощущаться как доступ к массиву. Он написан для C ++ 17 и работает с Visual Studios, g ++ и Clang. Библиотека имеет только заголовок, то есть вам нужно только скопировать «Reflect.h» в ваш проект, чтобы использовать ее.
Для отраженных структур или классов необходим макрос REFLECT, в котором вы указываете имя класса, который вы отображаете, и имена полей.
Это все, что нужно, дополнительный код не требуется для настройки отражения. При желании вы можете указать суперклассы (в скобках первого аргумента) и аннотации полей (в скобках, предшествующих полю, которое вы хотите аннотировать), чтобы иметь возможность проходить через суперклассы или добавлять дополнительную информацию времени компиляции в поле (например, Json: Игнорируйте).
Цикл по полям может быть так же просто, как ...
Вы можете перебирать экземпляр объекта для доступа к значениям полей (которые вы можете читать или изменять) и информации о типах полей ...
JSON библиотека построена на вершине RandomAccessReflection , которая автоматически идентифицирует соответствующие выходные JSON - представления для чтения или записи, и может рекурсивно пройти любые отраженные поля, а также массивы и STL контейнеры.
Вышесказанное можно запустить так ...
Смотрите также...
источник
Отражение в C ++ очень полезно, в тех случаях, когда вам нужно запустить какой-то метод для каждого члена (например: сериализация, хеширование, сравнение). Я пришел с общим решением, с очень простым синтаксисом:
Где ENUMERATE_MEMBERS - это макрос, который описан позже (UPDATE):
Предположим, мы определили функцию сериализации для int и std :: string следующим образом:
И у нас есть универсальная функция рядом с «секретным макросом»;)
Теперь вы можете написать
Таким образом, имея макрос ENUMERATE_MEMBERS в определении структуры, вы можете создавать сериализацию, сравнение, хэширование и другие элементы, не касаясь исходного типа, единственное требование - реализовать метод «EnumerateWith» для каждого типа, который не является перечисляемым, для каждого перечислителя (например, BinaryWriter) , Обычно вам нужно реализовать 10-20 «простых» типов для поддержки любого типа в вашем проекте.
Этот макрос должен иметь нулевые накладные расходы для структурирования создания / уничтожения во время выполнения, и код T.EnumerateWith () должен генерироваться по требованию, что может быть достигнуто с помощью функции встроенного шаблона, поэтому единственные накладные расходы в Все дело в том, чтобы добавить ENUMERATE_MEMBERS (m1, m2, m3 ...) к каждой структуре, в то время как реализация конкретного метода для каждого типа члена является обязательной в любом решении, поэтому я не принимаю это как накладные расходы.
ОБНОВЛЕНИЕ: Существует очень простая реализация макроса ENUMERATE_MEMBERS (однако его можно немного расширить для поддержки наследования из перечисляемой структуры)
И вам не нужна никакая сторонняя библиотека для этих 15 строк кода;)
источник
С помощью BOOST_HANA_DEFINE_STRUCT из библиотеки Boost :: Hana вы можете получить интересные функции статического отражения для конструкций .
Hana достаточно универсален не только для того сценария, который вы имеете в виду, но и для большого количества метапрограммирования шаблонов.
источник
Если вы объявите указатель на функцию, подобную этой:
Вы можете назначить место в памяти для этой функции следующим образом (требуется
libdl
иdlopen
)Чтобы загрузить локальный символ с помощью косвенного обращения, вы можете использовать
dlopen
в вызывающем двоичном (argv[0]
).Единственное требование для этого (кроме
dlopen()
,libdl
иdlfcn.h
) - знание аргументов и типа функции.источник