模板(.tpp)文件包含警卫

dav*_*ave 13 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
Run Code Online (Sandbox Code Playgroud)

myclass.tpp

#ifndef MYCLASS_TPP //needed?
#define MYCLASS_TPP //needed?

template<typename T>
T MyClass<T>::foo(T obj)
{
    return obj;
}

#endif //needed?
Run Code Online (Sandbox Code Playgroud)

YSC*_*YSC 14

我是否需要在.tpp文件中包含防护,或者将它们放在.hpp文件中是否足够?

永远不需要包括警卫:他们只是非常有用,便宜,无中断和预期.所以,是的,你应该使用标题保护来保护这两个文件:

  • 非常有用:它们允许您从多个文件声明依赖项,而无需跟踪已包含的文件.
  • 便宜:这只是一些预编译令牌.
  • 无中断:它们适合大多数用例#include(我有一个不知道如何编写宏的同事所以他#include实现文件*facepalm*).
  • 预计:开发人员知道他们是什么,几乎没有注意到他们; 相反,丢失的头文件包括警卫唤醒我们并添加到全局wtf /行计数器.

我借此机会强调StoryTeller的评论:

#error如果没有定义hpp防护,我会更进一步并添加一个描述性指令.只是首先提供一些保护,包括tpp.

哪个将翻译为:

#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
Run Code Online (Sandbox Code Playgroud)

注意:如果首先是翻译单元#include <myclass.hpp>,那么#include <myclass.tpp>不会触发错误,一切都很好.

  • @dave否.如果您的用户首先包含`myclass.hpp`然后是`myclass.tpp`,则错误不会触发. (2认同)
  • @francesco头发分裂的答案是"`#pragma once`也可以在基本上任何编译器中完成它". (2认同)