& quot; множественное определение … & quot; используя 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 function
std :: iterator_traits :: iterator_category std :: __ iterator_category (char * const&) ‘:
/…/Files/Include/../../../arpack++/include/arerror.h:163: множественное определение ArpackError::code'
/.../Files/Includes/../../../arpack++/include/arerror.h:163: first defined here
/tmp/ccruWhMn.o: In function
std :: vector> :: max_size () const ‘:

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

0

Решение

В общем, самый простой способ работы с библиотеками только с заголовками — это расширение вашего кода только с помощью заголовков. Если вы используете правильные средства защиты заголовков, это устранит проблему множественных определений вашего кода. Если у вас есть большая база существующего кода, я бы предложил переименовать все ваши *.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 и ссылка.

0

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

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

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

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

0