Я хотел бы передать указатель на этот контейнер в функцию, которая будет обращаться к данным контейнера как к универсальным данным - то есть char*
или void*
.Подумайте о сериализации.
Не может быть сделано вообще, потому что вы ничего не знаете о T
.Как правило, типы нельзя обрабатывать (например, копировать, получать к ним доступ и т. Д.) В виде необработанных больших двоичных объектов с помощью char *
или аналогичных.
Поэтому вам необходимо ограничить то, что может быть T
, в идеальном случае принудительно применяя егоиначе никогда не используйте его для T
s, который вызовет неопределенное поведение.Например, вы можете утверждать, что std::is_trivially_copyable_v<T>
выполнено.Тем не менее, вам придется учитывать другие возможные проблемы при обработке таких данных, как порядковый номер и упаковка.
Эта функция несколько сложна, поэтому было бы неплохо не указывать ее в заголовке из-заШаблоны.
Не уверен, что вы подразумеваете под этим.Компиляторы могут очень легко обрабатывать заголовки и, в частности, огромное количество кода шаблона.Пока вы не достигнете уровней, например, некоторых библиотек Boost, ваше время компиляции не взорвется.
Я решил вообще избегать шаблонов, заставив MyContainer
содержать контейнер некоторого абстрактного MyData
класс с функцией virtual void Serialize(void *dest) = 0;
.Пользователи будут создавать подклассы MyData
для предоставления своих типов и сериализации, но кажется, что это становится довольно сложно.Также неэффективно, поскольку требует сохранения указателей на MyData
, чтобы избежать нарезки объектов, а MyData
обычно довольно мал, и контейнер будет содержать большие объемы (большое количество хранилищ указателей и разыменование).
InВообще, если вы хотите шаблон, сделайте шаблон.Использование динамической диспетчеризации для этого, вероятно, приведет к снижению производительности, особенно если вам придется проходить диспетчеризацию даже для простых типов.
В заключение я бы посоветовал взглянуть на некоторые доступные библиотеки сериализации, чтобы увидетькак они достигли этого, не только с точки зрения производительности, но и с точки зрения простоты использования, интеграции с существующим кодом и т. д. Например, Boost Serialization и Буферы протокола Google .