0

在我当前的项目中,我正在使用 arpackpp 界面。整个库都写在.h文件中,所以不需要编译库。我现在面临的问题 - 当我在我的一些arpackpp文件中包含一些头文件时main.cpp,我收到以下错误:

/.../Files/Includes/../../../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了类 in包含了所有类和函数main.cpp,这变得非常混乱。这个问题有解决方法吗?为什么不包括警卫来(#ifndef...#endif)防止这个问题?

4

2 回答 2

1

首先,包含保护在这一点上没有帮助,因为它们只能防止在项目文件的依赖关系图的“子树”中包含多个标题。换句话说:如果你在同一个项目的两个完全分开的文件中包含一个头文件,c++ 预处理器将用#include <header.h>头文件中指定的代码独立地替换两次。只要标头仅包含声明,这完全没问题。

在您的情况下(以及在许多其他仅标头库的情况下),标头中也提供了定义。所以不幸的是(据我所知),除了在项目中包含一次包含定义的文件之外,没有其他优雅的方法。https://github.com/m-reuter/arpackpp/blob/master/include/README明确说明了哪些文件包含定义。

然而,一些库提供预处理器宏来触发包含所提供头文件的定义(例如https://github.com/nothings/stb)。也许arpackpp提供了类似的机制。

于 2016-07-29T09:31:42.177 回答
0

通常,使用仅标头库的最简单方法是仅使用标头扩展代码。如果您使用正确的标头保护,这将消除您的代码的多个定义的问题。如果您有大量现有代码,那么我建议您将所有*.cpp文件重命名为*.hpp(c++ 头文件),然后添加合适的头保护。此外,处理此基本代码的一种便捷方法是创建一个额外的头文件config.hpp并将所有其他头文件包含在该文件中。config.hpp然后在您的 main.c 中包含该文件很简单。

例如

// 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和链接。

于 2016-07-29T10:39:16.863 回答