Как бы вы писали библиотеку, которая при включении перегружает оператор <<
для любого * существующего контейнера STL?
- Кроме адаптеров, таких как стек и очередь, поскольку вы не можете их перебирать.
Одно из требований, предъявляемых к себе, состоит в том, что оно не должно содержать никаких файлов заголовков контейнеров. Это наполнило бы окончательный исполняемый файл излишне. Имеет смысл включить этот заголовок после контейнеров, с которыми я хотел бы работать. Это ограничение подразумевает использование templates
или macros
.
Я ищу советы и указатели, поэтому, пожалуйста, не просто публикуйте полностью рабочий код, который может это сделать! Реализация этого сама является частью процесса обучения. Небольшие фрагменты кода, которые демонстрируют, как некоторые вещи работают, приветствуются.
Что я сделал до этого момента:
Я перегрузил оператор <<
для каждого контейнера с другой подписью шаблона. Проблема, с которой я столкнулся с этим подходом, заключается в том, что существуют контейнеры с одинаковым количеством параметров шаблона, но некоторые содержат std::pair
-s, другие single values
. Точнее, это случай std::map
и std::multimap
vs std::unordered_set
и std::unordered_multiset
.
Это столкновение заставляет меня либо реализовать нетермическую версию одной из пар, либо создать способ различать std::pair
-s и single values
. Однако я действительно не знаю, как сделать вторую. Причина в том, что я не "как это сделать" напрямую, так это то, что я начинаю верить, что этого можно избежать полностью с лучшим общим дизайном.
Заранее благодарю!
Что сработало для меня:
- Перегрузка
operator<<
дляstd::pair
- Перегрузка
operator<<
для каждого контейнера STL с разными аргументами шаблонаПримечание:
-
template <typename T1>
иtemplate <typename T1, typename T2>
отличаются -
template <typename T1, typename T2>
иtemplate <typename T1, size_t T2>
являются отличается -
template <typename T1, typename T2>
иtemplate <typename C1, typename C2>
НЕ разные
-
- Поместите их в пространство имен, чтобы убедиться, что ваши операторы не столкнутся с другими операциями, которые вам могут понадобиться в будущем.
Используйте "шаблоны в шаблонах", поэтому, например, функция будет выглядеть так:
template <typename Type, template <typename TYPE> class TClass>
void func(TClass<Type>& tc) {
if (tc.somethingTrue())
tc.doStuff();
}