在命名空间内定义函数时引发链接器错误? [复制]
Posted
技术标签:
【中文标题】在命名空间内定义函数时引发链接器错误? [复制]【英文标题】:Linker errors thrown when defining a function inside of a namespace? [duplicate] 【发布时间】:2020-07-25 21:37:50 【问题描述】:为什么我无法在 .cpp 文件(不是 main.cpp)的命名空间内定义函数?
例如,假设我想将我的代码分成 2 个不同的文件,main.cpp,然后是 lib.cpp(带有关联的 lib.h 文件)。
以下设置会引发链接器错误: lib.h:
#ifndef LIB_H_
#define LIB_H_
namespace a
void foo();
#endif
lib.cpp:
#include "lib.h"
using namespace a;
void foo()
std::cout<<"Hello World!"<<std::endl;
main.cpp:
#include "lib.h"
int main()
a::foo();
return 0;
不过,我能想到的几乎任何其他变体都有效。
在 lib.h 文件而不是 lib.cpp 中定义函数可以工作 删除命名空间有效 保留命名空间,而是将 foo 作为公共方法 我在主函数中实例化然后调用的类,工作在我看来这可能是一种约定俗成的事情?鼓励人们使用类或在 .h 文件中完全定义函数?我得到的链接器错误是“undefined symbols(a::foo()) for architecture...”
为什么会这样? 我在使用 CLion 的 Mac 上。
【问题讨论】:
你已经声明了一个函数a::foo
,但是你定义了一个全局命名空间函数::foo
。您的声明应在namespace
块内,或声明为void a::foo()
; using namespace
声明不足。
【参考方案1】:
using namespace a;
不是在命名空间内定义函数的方法。
语法与声明相同:namespace a ...
#include "lib.h"
namespace a
void foo()
std::cout<<"Hello World!"<<std::endl;
更多详情请参考:Namespaces。
【讨论】:
只是澄清一下-即使我在 lib.h 中使用命名空间 a... 声明了该函数,我也无法使用“使用命名空间”语法来定义它? 正确。 “使用命名空间”语法始终是只读的。【参考方案2】:你必须添加
target_link_libraries(<name of your executable> <name of your library>)
将库符号和函数链接到您的可执行文件。
您正在全局命名空间中定义函数。
在lib.cpp
中这样定义你的函数
void a::foo()
...
见下面代码中的cmets
lib.h
#ifndef LIB_H_
#define LIB_H_
namespace a
void foo(); // declaring a::foo()
#endif
lib.cpp
#include "lib.h"
using namespace a;
void foo() // defining ::foo() and thats why calling foo() without namespace a works
std::cout<<"Hello World!"<<std::endl;
【讨论】:
谢谢!但是我的 cmake 已经在使用 add_library() 和 target_link_libraries(),它们似乎也能正常工作,因为我可以在 .h 文件中声明类并在我的 .cpp 文件中定义它们,即使它们是命名空间以上是关于在命名空间内定义函数时引发链接器错误? [复制]的主要内容,如果未能解决你的问题,请参考以下文章