模板(.tpp)文件包括防护

时间:2019-01-25 09:54:09

标签: c++ templates include-guards

在编写模板类时,我想将实现移动到另一个文件(myclass.tpp)中,并将其包含在主标头(myclass.hpp)的底部。

我的问题是:我需要在.tpp文件中包含防护措施,还是在.hpp文件中包含防护措施就足够了?

示例代码:

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?

2 个答案:

答案 0 :(得分:13)

  

我是否需要在.tpp文件中包含防护,还是在.hpp文件中包含防护就足够了?

永远不需要 包含防护:它们只是非常有用,便宜,无干扰且可以预期的。因此,是的,您应该使用标头防护来保护这两个文件:

  • 非常有用:它们使您可以声明多个文件的依赖关系,而无需跟踪已包含哪些文件。
  • 便宜:这只是一些预编译令牌。
  • 无干扰:它们非常适合#include的大多数用例(我有一位不知道如何编写宏的同事,所以他{{1} } d实现文件 * facepalm * )。
  • 期望:开发人员知道自己是什么,几乎没有注意到它们;相反,缺少头文件的头文件会导致我们醒来并添加到全局wtf / line计数器中。

我借此机会重点介绍StoryTeller的评论:

  

如果未定义hpp防护,我会更进一步并添加一个描述性的#include指令。只是为了向包括tpp在内的人们提供一点保护。

这将翻译为:

#error

注意:如果翻译单元首先#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 ,然后#include <myclass.hpp>,则不会引发错误,一切都很好。

答案 1 :(得分:3)

仅在所有头文件中使用pragma once。编译器将确保您的文件仅被包含一次。编译器可能只会在非常不合理的情况下无法识别:有人使用硬链接来构造其包含目录。这是谁如果某人找不到其文件的唯一名称,为什么他会更熟练地为所有头文件的每个include防护找到唯一的名称?

另一方面,由于宏的名称不是唯一的,包括复制/粘贴或通过首先复制另一个而创建的头文件,等等,所以包括保护可能会被破坏...

如何选择唯一的宏名称<project name>_<filename>?与基于整个根目录结构的唯一性相比,它有什么独特性?

因此,最后,应该在包含保护或pragma once之间进行选择时,应考虑确保唯一性所需的工作成本:

1-对于pragma once,您只需确保不会由于硬链接而弄乱系统的结构化目录。

2-对于系统上每个文件的 include guard ,您应确保宏名称是唯一的。

我的意思是,作为一名经理,评估这项工作的成本和失败风险的确只有一种选择。包含防护仅在不执行评估时才使用:这是一个未决定的事情。

相关问题