命名空间函数的多重定义[重复]

Posted

技术标签:

【中文标题】命名空间函数的多重定义[重复]【英文标题】:Multiple definition of namespace function [duplicate] 【发布时间】:2018-05-23 07:37:42 【问题描述】:

我只是想不通为什么它不能编译。

我有三个文件:

main.cpp

#include "expression.h"

int main(int argc, char** argv)


    return 0;

表达式.h

#ifndef _EXPRESSION_H
#define _EXPRESSION_H

namespace OP

  char getSymbol(const unsigned char& o)
  
    return '-';
  
;

#endif /* _EXPRESSION_H */

和表达式.cpp

#include "expression.h"

(Ofc 里面还有更多内容,但即使我评论了除了#include 之外的所有内容,它也不起作用)

我用它编译

g++ main.cpp expression.cpp -o main.exe

这是我得到的错误:

C:\Users\SCHIER~1\AppData\Local\Temp\ccNPDxb6.o:expression.cpp:(.text+0x0): multiple definition of `OP::getSymbol(unsigned char const&)'
C:\Users\SCHIER~1\AppData\Local\Temp\cc6W7Cpm.o:main.cpp:(.text+0x0): first defined here
collect2.exe: error: ld returned 1 exit status

问题是,它似乎解析了两次expression.h。如果我只是使用main.cppexpression.cpp 编译它,我不会收到错误消息。编译器只是忽略我的#ifndef 并继续...

有什么线索吗?

【问题讨论】:

对于每个文件,都会将函数的定义添加到生成的目标文件中。当程序被链接时,链接器看到同一个函数的两个版本并且不知道使用哪个版本。修复:在头文件中将函数声明为inline > 来自en.cppreference.com/w/cpp/language/definition:程序中可以有多个定义,只要每个定义出现在不同的翻译单元中,以下各项:类类型、枚举类型、具有外部链接的 内联函数 具有外部链接的内联变量 (C++17 起)、类模板、非静态函数模板、类模板的静态数据成员、成员函数类模板、部分模板特化、概念(C++20 起)只要满足以下所有条件: 【参考方案1】:

问题是,它似乎解析了 expression.h 两次。

当然可以。您将它包含在两个不同的 cpp 文件中。每个包含都将标头的内容转储到该翻译单元中,因此您会获得同一函数的两个定义,从而使链接器理所当然地抱怨。这与包含保护无关,它可以防止您在同一个文件中意外包含两次。

但是,您可以在标题中定义函数。只要它被标记为内联。这样做:

namespace OP

  inline char getSymbol(const unsigned char& o)
  
    return '-';
  

inline 这里承诺所有这些功能都是完全相同的。因此,多个定义实际上被认为是相同的。但是请注意不要违背这个承诺(不要使用任何可以根据包含的位置更改函数体的构造)。

顺便说一句,命名空间不需要以; 终止,所以我冒昧地删除了它。

【讨论】:

以上是关于命名空间函数的多重定义[重复]的主要内容,如果未能解决你的问题,请参考以下文章

使用在同一命名空间中定义的构造函数实例化命名空间中的对象。 C++

PHP 命名空间(namespace)

命名空间:不只是代码封装

C++入门学习

为 Laravel 8 路由定义命名空间 [重复]

命名空间内与类内的范围函数[重复]