"multiple definition of ..." 使用 arpackpp
"multiple definition of ..." using arpackpp
在我当前的项目中,我使用的是 arpackpp 界面。整个库写在 .h
个文件中,因此不需要编译库。我现在面临的问题 - 当我在我的一些文件中包含一些 arpackpp
头文件时,这些文件不是 main.cpp
,我得到以下错误:
/.../Files/Includes/../../../arpack++/include/arerror.h:163: multiple definition of 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/Includes/../../../arpack++/include/arerror.h:163: multiple definition of ArpackError::code'
/.../Files/Includes/../../../arpack++/include/arerror.h:163: first defined here
/tmp/ccruWhMn.o: In function
std::vector >::max_size() const':
用于链接所有 .o
文件时的几个 arpackpp
函数。正如我在几个线程中读到的那样,问题是我实际上包括了函数的实例化,这通常应该避免。
因为我不想更改整个库,所以我在 main.cpp
中包含了所有 类 和使用 arpackpp
类 的函数,这变得相当混乱。这个问题有解决方法吗?为什么不包括守卫 (#ifndef...#endif)
来防止这个问题?
首先,include guards 在这一点上没有帮助,因为它们只能防止在项目文件的依赖关系图中的 "subtree" 中多次包含 header。换句话说:如果您在同一项目的两个完全独立的文件中包含 header,C++ 预处理器将替换 #include <header.h>
两次,并且独立地使用 header 中指定的代码。只要 header 只包含声明,这就完全没问题。
对于您的情况(以及许多其他 header-only 库的情况),header 中也提供了定义。所以不幸的是(据我所知),除了在你的项目中包含一次 definition-containing 文件之外,没有其他优雅的方法。 https://github.com/m-reuter/arpackpp/blob/master/include/README 明确指出哪些文件包含定义。
然而,一些库提供预处理器宏来触发包含所提供的 header 文件的定义(例如 https://github.com/nothings/stb)。也许 arpackpp
提供了类似的机制。
一般来说,使用仅 header 库的最简单方法是仅使用 header 扩展您的代码。如果您使用正确的 header 守卫,这将消除您的代码的多个定义的问题。如果您有大量现有代码,那么我建议您将所有 *.cpp
文件重命名为 *.hpp
(c++ header 文件),然后添加合适的 header 守卫。此外,处理此基本代码的一种简便方法是创建一个额外的 header 文件 config.hpp
并将所有其他 header 包含在该文件中。然后在您的 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
和 link.
在我当前的项目中,我使用的是 arpackpp 界面。整个库写在 .h
个文件中,因此不需要编译库。我现在面临的问题 - 当我在我的一些文件中包含一些 arpackpp
头文件时,这些文件不是 main.cpp
,我得到以下错误:
/.../Files/Includes/../../../arpack++/include/arerror.h:163: multiple definition of
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/Includes/../../../arpack++/include/arerror.h:163: multiple definition ofArpackError::code' /.../Files/Includes/../../../arpack++/include/arerror.h:163: first defined here /tmp/ccruWhMn.o: In function
std::vector >::max_size() const':
用于链接所有 .o
文件时的几个 arpackpp
函数。正如我在几个线程中读到的那样,问题是我实际上包括了函数的实例化,这通常应该避免。
因为我不想更改整个库,所以我在 main.cpp
中包含了所有 类 和使用 arpackpp
类 的函数,这变得相当混乱。这个问题有解决方法吗?为什么不包括守卫 (#ifndef...#endif)
来防止这个问题?
首先,include guards 在这一点上没有帮助,因为它们只能防止在项目文件的依赖关系图中的 "subtree" 中多次包含 header。换句话说:如果您在同一项目的两个完全独立的文件中包含 header,C++ 预处理器将替换 #include <header.h>
两次,并且独立地使用 header 中指定的代码。只要 header 只包含声明,这就完全没问题。
对于您的情况(以及许多其他 header-only 库的情况),header 中也提供了定义。所以不幸的是(据我所知),除了在你的项目中包含一次 definition-containing 文件之外,没有其他优雅的方法。 https://github.com/m-reuter/arpackpp/blob/master/include/README 明确指出哪些文件包含定义。
然而,一些库提供预处理器宏来触发包含所提供的 header 文件的定义(例如 https://github.com/nothings/stb)。也许 arpackpp
提供了类似的机制。
一般来说,使用仅 header 库的最简单方法是仅使用 header 扩展您的代码。如果您使用正确的 header 守卫,这将消除您的代码的多个定义的问题。如果您有大量现有代码,那么我建议您将所有 *.cpp
文件重命名为 *.hpp
(c++ header 文件),然后添加合适的 header 守卫。此外,处理此基本代码的一种简便方法是创建一个额外的 header 文件 config.hpp
并将所有其他 header 包含在该文件中。然后在您的 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
和 link.