我正在阅读有关内部和外部链接的信息,我发现默认情况下函数具有外部链接。
所以我在想是否可以在头文件管理器中声明一个函数,并在不同的翻译单元中提供它的多个定义。
到目前为止,我确实在头文件中声明了一个功能
void fct();
并在两个文件中提供 2 个定义,每个定义都包含在一个匿名命名空间中:
namespace
{
void fct()
{
}
}
但是我没有看到这如何成为在不同TU中使用函数的多个定义的良好检查。
有人可以给我看一个简单的例子(即使使用内联) 谢谢
我可以在不同的 TU 中提供相同的函数定义吗?
如果函数不是内联声明的,则 no;这将违反一个定义规则。
具有外部链接的内联函数可以在多个 TU 中定义 - 附加要求定义必须相同。事实上,内联声明将强制要求在使用该函数的所有 TU 中提供定义。
并在两个文件中提供 2 个定义,每个定义都包含在一个匿名命名空间中:
这并不违反标准规则。这两个函数不一样,也不和全局::fct
不一样。
但是我没有看到这如何成为在不同TU中使用函数的多个定义的良好检查。
有人可以给我看一个简单的例子(即使使用内联)谢谢
给你:
// header.hpp
inline void foo() {}
// a.cpp
#include "header.hpp"
// b.cpp
#include "header.hpp"
这里有两个 TU,每个都包含函数的定义::foo
,包含在同一个标头中。这是允许的,因为函数是内联声明的。
标准报价(当前草案,不相关细节由我编辑):
单定义规则 [basic.def.odr]
一个。。。功能。。。在先前定义必须可访问的情况下,不得定义([模块.reach]);如果事先声明在另一个翻译单元中,则无需诊断。
。
每个程序都应该只包含该程序中使用的每个非内联函数或变量的一个定义,除了丢弃的语句之外;不需要诊断。内联函数或变量的定义应在丢弃语句之外使用的每个翻译单元中都可以访问。
。
可以有多个定义...带外部链接的内联功能([dcl.inline]) ...在程序中,前提是在出现定义的点不一定可以访问先前定义([module.reach]),并且定义满足以下要求。 ...除非在出现后定义时可以访问先前的定义,否则不需要诊断。 给定这样一个在多个翻译单元中定义的名为 D 的实体,则
- D的每个定义应由相同的令牌序列组成;和
~- 其他限制的长度列表 ~