[英]Template (.tpp) file include guards
When writing templated classes, I like to move the implementation into a different file ( myclass.tpp
) and include it at the bottom of the main header ( myclass.hpp
).在编写模板化类时,我喜欢将实现移动到不同的文件 ( myclass.tpp
) 并将其包含在主标题 ( myclass.hpp
) 的底部。
My Question is: do I need include guards in the .tpp
file or is it sufficient to have them in the .hpp
file?我的问题是:我需要包括在警卫.tpp
文件还是足以让他们在.hpp
文件?
Example code:示例代码:
myclass.hpp
#ifndef MYCLASS_HPP
#define MYCLASS_HPP
template<typename T>
class MyClass
{
public:
T foo(T obj);
};
//include template implemetation
#include "myclass.tpp"
#endif
myclass.tpp
#ifndef MYCLASS_TPP //needed?
#define MYCLASS_TPP //needed?
template<typename T>
T MyClass<T>::foo(T obj)
{
return obj;
}
#endif //needed?
Do I need include guards in the .tpp file or is it sufficient to have them in the .hpp file?我需要在 .tpp 文件中包含警卫还是将它们放在 .hpp 文件中就足够了?
Include guards are never needed : they're just terribly useful, cheap, non-disruptive and expected.永远不需要包含守卫:它们非常有用、便宜、无破坏性和预期。 So Yes, you should protect both files with header guards:所以是的,你应该用头文件保护这两个文件:
#include
(I've had a colleague who didn't know how to write macros so he #include
d implementation files facepalm ).非破坏性:它们非常适合#include
大多数用例(我有一位同事不知道如何编写宏,所以他#include
d 实现文件facepalm )。I take the opportunity to highlight the comment from StoryTeller:我借此机会强调 StoryTeller 的评论:
I'd go a step further and add a descriptive
#error
directive if the hpp guard is not defined.如果未定义 hpp 防护,我会更进一步并添加一个描述性#error
指令。 Just to offer a little protection from people including the tpp first.只是为了提供一点保护,包括首先对人的保护。
Which will translate to:这将转化为:
#ifndef MYCLASS_TPP
#define MYCLASS_TPP
#ifndef MYCLASS_HPP
#error __FILE__ should only be included from myclass.hpp.
#endif // MYCLASS_HPP
template<typename T>
T MyClass<T>::foo(T obj)
{
return obj;
}
#endif // MYCLASS_TPP
Notice: if a translation unit first #include <myclass.hpp>
and then #include <myclass.tpp>
, no error is fired and everything is fine.注意:如果翻译单元首先#include <myclass.hpp>
然后#include <myclass.tpp>
,则不会触发任何错误并且一切正常。
Just use pragma once
in all headers file.只需在所有头文件中使用pragma once
。 The compiler will ensure your file will be included only once.编译器将确保您的文件只会被包含一次。 The compiler may only fail to recognize in very unreasonable condition: someone structure its include directories using hard-link.编译器可能只会在非常不合理的情况下无法识别:有人使用硬链接构建其包含目录。 Who does this?谁做这个? If someone cannot find a unique name for its file, why would he be more skilled to find a unique name for each include guard for all the header files?如果某人找不到其文件的唯一名称,为什么他会更熟练地为所有头文件的每个包含保护找到唯一名称?
On the other hand, include guard may be broken because the name of the macro will not be that unique, because of a copy/paste, or a header file created by first copying an other, etc...另一方面,包含保护可能会被破坏,因为宏的名称不会那么唯一,因为复制/粘贴,或者通过首先复制另一个创建的头文件等...
How are chosen the unique macro name : <project name>_<filename>
?如何选择唯一的宏名称: <project name>_<filename>
? How could it be more unique than a uniqueness based on the entire root directory structure?它怎么可能比基于整个根目录结构的唯一性更独特?
So in the end, one should consider when choosing between include guard or pragma once
, the cost of the job that is necessary to ensure uniqueness:因此,最后,在选择 include guard 或pragma once
时应考虑确保唯一性所需的工作成本:
1 - For pragma once
you only have to ensure that the directory structured of your system is not messed-out thanks to hard links. 1 - 对于pragma once
您只需确保系统的目录结构不会因硬链接而混乱。
2 - For include guard for each file on your system you should ensure that the macro name is unique. 2 - 对于系统上每个文件的包含保护,您应该确保宏名称是唯一的。
I mean as a manager, evaluating the cost of this job and the failure risk does let only one option.我的意思是,作为一名经理,评估这项工作的成本和失败风险确实只有一种选择。 Include guard are used only when no evaluation is performed: it is a non decision.仅当不执行评估时才使用包含保护:这是一个非决定。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.