Библиотеки только для заголовков и множественные ошибки определения - PullRequest
14 голосов
/ 20 октября 2010

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

Ответы [ 4 ]

27 голосов
/ 20 октября 2010

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

namespace fancy_schmancy
{
  inline void my_fn()
  {
    // magic happens
  }
};
5 голосов
/ 20 октября 2010

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

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

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

2 голосов
/ 20 октября 2010

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

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

1 голос
/ 20 октября 2010

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

...