【问题标题】: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 声明不足。

标签: c++ cmake header-files clion


【解决方案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 文件中定义它们,即使它们是命名空间
猜你喜欢
  • 2015-10-31
  • 1970-01-01
  • 1970-01-01
  • 2012-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-08
  • 2014-07-07
相关资源
最近更新 更多