在模板类周围包含守卫是否明智?
每次使用不同的实现引用模板类时,不应该重新解析它们吗?
注意在 Visual C++ 2008 中,将两者结合起来没有错误...
在模板类周围包含守卫是否明智?
每次使用不同的实现引用模板类时,不应该重新解析它们吗?
注意在 Visual C++ 2008 中,将两者结合起来没有错误...
你需要包括警卫。考虑这段代码:
// this is t.h
template <typename T>
void f( T t ) {
}
// this is t.cpp
#include "t.h"
#include "t.h"
int main() {
f( 1 );
}
这给出了错误:
t.h:2: error: redefinition of 'template<class T> void f(T)'
t.h:2: error: 'template<class T> void f(T)' previously declared here
此外,包含模板的标头通常也包含非模板代码。
模板定义应该被解析一次(这里有两个阶段名称查找之类的东西,以便可以立即给出尽可能多的错误而无需实例化)。实例化是使用当时构建的内部数据结构完成的。
模板定义通常(即,如果您没有使用export
或做一些特殊的事情)在头文件中,应该有它们的包含保护。为模板定义添加一个无用但无害。
简短回答:您计划在任何定义中多次包含的每个单元都应该有一个标题保护。那是有或没有模板。
回答您的第一个问题:是的,在模板类周围包含守卫是明智且强制性的。或者更严格地围绕每个头文件的全部内容。
当您在头文件中有内容时,这是遵守单一定义规则的方法,以便它可以共享并且仍然安全。可能还有其他头文件包括您的。当编译器编译一个模块文件时,它可能会#include
多次看到你的头文件,但是守卫会在第二次和随后的时间里启动,以确保编译器只看到一次内容。
编译器重新解析任何东西都没有关系。这就是它的工作。您只需提供一次内容,然后编译器就会看到它,并且可以根据需要多次再次引用它。