我应该何时考虑使用在文件范围定义的静态函数?
我通常在一个这样的函数中完成的任务并不真正属于任何类的成员函数时,并且只在某个源文件中需要(重复)这样的任务时使用它们。
我的用法是否与此功能存在的原因一致?或者我是否劫持了一个其他意图的概念?
答案 0 :(得分:3)
这是对文件范围静态函数的完全有效使用,但请记住,静态的这种用法已经被弃用了很长时间。通常首选使用匿名命名空间。
答案 1 :(得分:1)
当有关函数和/或数据不属于类接口而非实现细节时,我会做类似的事情。
但我不使用关键字static。相反,我将函数和/或数据放在一个未命名的命名空间中。
答案 2 :(得分:1)
首先,您要查找的术语是内部链接。你的问题应该是:"哪些实体应该有内部联系?" static
关键字或者未命名的命名空间只是实现内部链接的实现机制。
现在答案应该是显而易见的:所有在单个翻译单元中只需要的实体可以给予内部链接,这样做有以下好处:一个是编译器可以利用实体无法获得的信息任何其他翻译单元都可以看到它,因此它可以避免发出可能需要的代码,或者更积极地内联。另一个原因是,如果您碰巧选择了在其他TU本地使用的名称,则可以最大程度地降低意外ODR违规的风险。
典型的例子是这样的:
<强> my_lib.hpp:强>
#ifndef H_MY_LIB
#define H_MY_LIB
namespace foo
{
void do_an_awesome_thing(void * p, std::size_t n);
}
#endif
<强> my_lib.cpp:强>
#include "my_lib.hpp"
namespace foo
{
namespace
{
void helper(void * p) { /* ... */ }
bool aux(std::size_t n, float f) { /* ... */ }
constexpr char usage[] = R"(This is how you do it...)";
constexpr float some_factor = 1.25;
}
void do_an_awesome_thing(void *p, std::size_t n)
{
if (!aux(n, some_factor)) { LOG_AND_DIE(usage); }
helper(p);
}
}
现在您可以确定您的翻译单元不会对您计划的其余部分造成任何不必要的链接时间负担。
未命名的命名空间的位置是一个品味问题;您可以将它放在通常的命名空间内,也可以放在顶层。效果是一样的。