C++ 中函数已定义错误
我有一个名为“SimpleFunctions.h”的文件,定义如下:
#ifndef SIMPLEFUNCTIONS_H
#define SIMPLEFUNCTIONS_H
namespace my_namespace {
double round(double r) { return (r > 0.0) ? floor(r + 0.5) : ceil(r - 0.5); }
float round(float r) { return round((double)r); }
}
#endif // SIMPLEFUNCTIONS_H
该文件以前仅包含在一个文件中,并且工作正常。
现在,今天我已将其包含在第二个文件中,但它不再起作用。在链接时,它告诉我该函数已在“firstfile.obj”中定义。
但是,由于我使用的是包含防护,因此我希望函数仅定义一次,或者我是否遗漏了某些内容?
I have a file called "SimpleFunctions.h" defined as follow:
#ifndef SIMPLEFUNCTIONS_H
#define SIMPLEFUNCTIONS_H
namespace my_namespace {
double round(double r) { return (r > 0.0) ? floor(r + 0.5) : ceil(r - 0.5); }
float round(float r) { return round((double)r); }
}
#endif // SIMPLEFUNCTIONS_H
This file was previously included in only one file and it was working fine.
Now today I have included it in a second file and it no longer works. At link time, it tells me that the function is already defined in "firstfile.obj".
However, since I am using include guards, I would expect the functions to be defined only once, or am I missing something?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
默认情况下,这些函数具有外部链接。这意味着每个翻译单元都有称为 double round(double r) 和 float round(float r) 的函数,这会导致链接时的名称冲突。
一些可能的解决方案是:
阅读更多内容:
什么是外部链接和内部链接?
通过这种方式,包含防护可以保护单个翻译单元免于多次包含头文件。这是一个与您在这里看到的不同的问题。
By default, these functions have external linkage. That means each translation unit has functions called double round(double r) and float round(float r), which causes a name collision at link time.
Some possible solutions are:
Read more here:
What is external linkage and internal linkage?
By the way, include guards protect a single translation unit from including a header file multiple times. That's a different issue that what you're seeing here.
使用 'inline'
编译器不一定会内联代码(尽管对于这个短函数来说可能会内联),但链接器不再将 is 视为单独的函数。
注意 - 包含防护会阻止同一包含文件多次包含在同一源文件(严格来说“编译单元”)中,但不会阻止它包含在链接在一起的单独源文件中。这就是为什么您通常在标头中声明它但在 ac 文件中定义该函数的原因
use 'inline'
The compiler won't necessarily inline the code (although for this short func it may) but the linker doesn't treat is as a separate function anymore.
Note - include guards stop the same include file being included more than once in the same source file (strictly speaking 'compilation unit') it doesn't stop it being included in separate source files that are linked together. That's why you normally declare it in a header but define the function in a c file
解决问题的更好方法是通过模板。如果您要执行以下操作,您的代码将可以正常编译:
您的链接器将停止抱怨,并且您将拥有一个满足您所有需求的函数。
该解决方案可以通过类型特征进行改进。请参阅boost::is_floating_point和<一个href="http://www.boost.org/doc/libs/1_49_0/libs/utility/enable_if.html" rel="nofollow">boost::enable_if
A better way to solve the problem is through templates. Your code will compile fine if you were to do something along the lines of:
Your linker will stop complaining and you'll have a single function for all of your needs.
This solution can be improved with type traits. See boost::is_floating_point and boost::enable_if