"множественное определение..." с использованием arpackpp

В моем текущем проекте я работаю с интерфейсом arpackpp. Вся библиотека написана на .h файлы, так что нет необходимости компилировать библиотеку. Проблема, с которой я сталкиваюсь сейчас - когда я включаю некоторые из arpackpp заголовочные файлы в некоторых моих файлах, которые не являются main.cppЯ получаю следующие ошибки:

/.../Files/Include/../../../arpack++/include/arerror.h:163: множественное определение ArpackError::Set(ArpackError::ErrorCode, std::string const&)' /.../Files/Includes/../../../arpack++/include/arerror.h:163: first defined here /tmp/ccruWhMn.o: In functionstd::iterator_traits::iterator_category std::__iterator_category(char* const&)': /.../Files/Includes/../../../arpack++/include/arerror.h:163: множественное определение ArpackError::code' /.../Files/Includes/../../../arpack++/include/arerror.h:163: first defined here /tmp/ccruWhMn.o: In functionstd::vector >::max_size() const':

для нескольких arpackpp функции при связывании всех .o файлы. Как я читал в нескольких потоках, проблема в том, что я фактически включаю создание экземпляров функций, которых обычно следует избегать. Поскольку я не хочу менять всю библиотеку, я включил все классы и функции, используя arpackpp занятия в main.cpp, который становится довольно грязным. Есть обходной путь для этой проблемы? И почему не включают охранников (#ifndef...#endif) предотвратить эту проблему?

2 ответа

Решение

В общем, самый простой способ работы с библиотеками только с заголовками - это расширение вашего кода только с помощью заголовков. Если вы используете правильные средства защиты заголовков, это устранит проблему множественных определений вашего кода. Если у вас есть большая база существующего кода, я бы предложил переименовать все ваши *.cpp файлы в *.hpp (заголовочные файлы C++), а затем добавьте подходящие охранники заголовков. Кроме того, удобный способ обработки этого кода базы - создать дополнительный заголовочный файл. config.hpp и включите все остальные заголовки в этот файл. Тогда в вашем main.c просто включите config.hpp файл.

например

// Config.hpp ------------------------------------------------=
#include "example.hpp"
#include "example1.hpp"
#include "example2.hpp"
// etc.

// main.cpp --------------------------------------------------=
#include "Config.hpp"

int main() {
  // Your code here.
  return 0;
}

Кроме того, если вы хотите продолжить работу со структурой вашего проекта, было бы просто разделить весь ваш код на функции, необходимые для доступа arpackcpp непосредственно. Затем включите их всех в один *.cpp файл и скомпилировать в *.o и ссылка.

Прежде всего, включенные средства защиты не помогают в этом пункте, поскольку они только предотвращают множественные включения заголовка в "поддерево" графа зависимостей файлов вашего проекта. Другими словами: если вы включите заголовок в два полностью разделенных файла одного и того же проекта, препроцессор C++ заменит #include <header.h> дважды и независимо по коду, указанному в шапке. Это прекрасно, если заголовок содержит только объявления.

В вашем случае (и в случае многих других библиотек только для заголовков) определения также содержатся в заголовках. Так что, к сожалению (насколько я знаю), нет другого элегантного способа, кроме как включить файлы, содержащие определения, один раз в ваш проект. https://github.com/m-reuter/arpackpp/blob/master/include/README прямо указывает, какие файлы содержат определения.

Однако некоторые библиотеки предоставляют макросы препроцессора, чтобы инициировать включение определений для предоставленных заголовочных файлов (например, https://github.com/nothings/stb). Может быть arpackpp предоставляет аналогичные механизмы.

Другие вопросы по тегам