Подтвердить что ты не робот

Библиотеки только для заголовков и многочисленные ошибки определения

Я хочу написать библиотеку, которую нужно использовать, вам нужно включить только один заголовочный файл. Однако, если у вас есть несколько исходных файлов и они включают заголовок в обоих, вы получите несколько ошибок определения, потому что библиотека объявлена ​​и определена в заголовке. Я видел библиотеки только для заголовков, в Boost, я думаю. Как они это сделали?

4b9b3361

Ответ 1

Объявите свои функции inline и поместите их в пространство имен, чтобы вы не сталкивались:

namespace fancy_schmancy
{
  inline void my_fn()
  {
    // magic happens
  }
};

Ответ 2

Основная причина, по которой Boost в основном относится только к заголовку, заключается в том, что он сильно ориентирован на шаблоны. Шаблоны обычно получают пропуск от одного правила определения. Фактически для эффективного использования шаблонов вы должны иметь определение, видимое в любой единицы перевода, которая использует шаблон.

Другим способом, связанным с одним правилом определения (ODR), является использование функций inline. Фактически, получение свободного прохода от ODR - это то, что действительно делает inline - тот факт, что он может встроить функцию, действительно является скорее дополнительным побочным эффектом.

Окончательный вариант (но, вероятно, не такой хороший) заключается в том, чтобы сделать ваши функции статичными. Это может привести к раздуванию кода, если компоновщик не может понять, что все эти экземпляры функций действительно одинаковы. Но я упомянул об этом для полноты. Обратите внимание, что компиляторы часто выполняют функции static, даже если они не помечены как inline.

Ответ 3

Boost использует библиотеки только для заголовков, потому что, подобно STL, он в основном построен с использованием шаблонов классов и функций, которые почти всегда имеют только заголовок.

Если вы не пишете шаблоны, я бы избегал включать код в ваши файлы заголовков - это больше проблем, чем того стоит. Сделайте это простой старой статической библиотекой.

Ответ 4

Есть много действительно богатых только Boost библиотек, но они, как правило, очень простые (и/или только шаблоны). Большие библиотеки выполняют один и тот же эффект с помощью некоторого обмана: у них есть "автоматическая привязка" (вы увидите, что этот термин используется здесь). У них по существу есть куча препроцессорных директив в заголовках, которые определяют соответствующий файл lib для вашей платформы и используют #pragma, чтобы дать ссылку компоновщику связать его. Таким образом, вам не нужно явно связывать его, но это все еще связаны.