Рассмотрите простую структуру:
struct abc
{
int a;
char b;
}
Я получил некоторое значение в переменной, определенной как ее структура, и теперь я хочу распечатать ниже.
*a = [some value]
b = [some character]*
Что лучший способ состоит в том, чтобы достигнуть этого для произвольной структуры, не имея необходимость писать, что дамп... (...) функционирует для каждой структуры, с которой я встречаюсь?
Для этого вам нужно «отражение». Отражение не предусмотрено изначально в C ++ или предоставляется только для минимальной информации (идентификаторы типов / имена).
Существуют библиотеки (например, CAMP ), которые реализуют функции отражения, поэтому, если вам ДЕЙСТВИТЕЛЬНО нужно отражение, вы должны использовать его.
Если вы используете C ++ в .NET, вы потенциально можете использовать материал System.Reflection , чтобы заглянуть внутрь вашего состав. Однако неуправляемый C ++ редко, если вообще когда-либо, хранит такие метаданные об объектах.
Кажется, вы уже нашли решение, но я немного расскажу.
То, что вы призываете, называется Отражением
, то есть способностью объекта описывать себя.
Большинство языков могут реализовать отражение благодаря метаданным. В Python, например, функции и атрибуты объекта хранятся в элементе словаря.
В C ++ нет собственной системы отражения, в отличие от C # или Java, которая предотвращает (например) такую автоматическую печать / сериализацию или десериализацию.
Однако C ++ имеет очень мощную поддержку метапрограммирования, которая позволяет нам (посредством использования шаблонов) имитировать отражение (во время компиляции). Обычно это делается с помощью Boost.Fusion , библиотеки, предназначенной для перехода от времени компиляции к времени выполнения.
Как показано в примере в вашей ссылке, макрос BOOST_FUSION_ADAPT_STRUCT
позволяет вам взять стандартную структуру
и предоставить ей требуемый интерфейс, который будет обрабатываться как Fusion.Sequence.
Другой пример - использование Fusion.Vector
или Fusion.Map
для хранения атрибутов класса и последующего предоставления этой Последовательности автоматическим методам печати / сериализации / десериализации.
Однако у этой системы есть ограничение: метапрограммирование плохо сочетается с объектно-ориентированным программированием.
struct Base { char a; }; // Adapt
struct Derived: Base { char b; }; // Adapt
void print(Base const& b) { boost::fusion::for_each<Base>(b, Print()); }
будет печатать только член Base
(здесь a
).При использовании полиморфизма вам необходимо использовать виртуальные
методы в тот или иной момент:)