шаблоны — Избежание циклических перегрузок и зависимостей специализации в библиотеке (AKA manual C ++ метод экспорта)

Есть моменты, когда я хочу перегружать или специализировать шаблоны, которые уже были вызваны ранее из-за циклических зависимостей.

Поскольку они являются шаблонами, решение обычно состоит в том, чтобы разделить объявление и определение.

Однако, если эти шаблоны должны быть частью библиотеки #included, это означает, что вам нужно два #include:

  • Один для декларация, который должен быть до все специализации.
  • Один для «поздно» определение, который должен быть после все специализации.

(Удаленный C ++ экспорт Ключевое слово (до C ++ 11) было потенциальным решением, но у него было множество проблем).

У кого-нибудь есть какие-то решения, чтобы избежать необходимости второго #include?


Я рассмотрел:

  1. Попытка создать некую единственную шаблонную функцию пересылки «late_call», которая определена в конце источника и использует некоторый механизм для вывода целевой функции из ее параметров. К сожалению, я могу видеть только, как это может работать в очень особых случаях.

    • [-] В основном не работает.
    • [-] Требуется #include в конце источника.
  2. Создание расширяемого списка заголовков для включения через препроцессор с последующим включением их всех в конце через один финальный #include.
    Можно взломать такой список с фиксированным количеством мест, используя множество #defines.

    • [-] Искусственный лимит.
    • [-] Использует макрос #include, который испортит некоторые инструменты.
    • [-] Гадкий как ад.
    • [-] Требуется #include в конце источника.
  3. Создание моей собственной команды pragma-type, а затем написание внешнего инструмента для запуска предварительно обработанного кода и перемещения перед компиляцией.

    • [+] Отлично работает.
    • [+] Ничего не нужно добавлять в конец источника.
    • [-] Это в значительной степени гарантирует, что никто никогда не захочет использовать мою библиотеку, и я, вероятно, тоже буду ненавидеть ее.
  4. Создание «late.hpp», в котором я добавляю #include для каждого позднего определения, защищенное #ifdefs, чтобы проверить, нужны ли они.

    • [-] Требуется #include в конце источника.
    • [-] Полностью нарушает модульность.
  5. В конце добавьте вручную список поздних определений заголовков.

    • [-] Разбивает модульность. Исходные файлы могут косвенно приобретать новые требования позднего определения, если изменяются другие реализации.
    • [-] Гадкий.
    • [-] Потенциальный источник ошибок.

2

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …