【发布时间】:2011-01-24 23:10:55
【问题描述】:
在模板类周围包含守卫是否明智?
每次你用不同的实现引用模板类时,不应该重新解析它们吗?
N.B 在 Visual C++ 2008 中,将两者结合起来没有错误...
【问题讨论】:
标签: c++ templates include-guards
在模板类周围包含守卫是否明智?
每次你用不同的实现引用模板类时,不应该重新解析它们吗?
N.B 在 Visual C++ 2008 中,将两者结合起来没有错误...
【问题讨论】:
标签: c++ templates include-guards
您需要包括警卫。考虑这段代码:
// 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 或做一些特殊的事情)在头文件中,应该有它们的包含保护。为模板定义添加一个无用但无害。
【讨论】:
#pragma once。
简短回答:您计划在任何定义中多次包含的每个单元都应该有一个标题保护。那是有或没有模板。
【讨论】:
回答您的第一个问题:是的,在模板类周围包含守卫是明智且强制性的。或者更严格地包围每个头文件的全部内容。
当您在头文件中有内容时,这是遵守单一定义规则的方法,以便它可以共享并且仍然安全。可能还有其他头文件包括您的。当编译器编译一个模块文件时,它可能会多次看到你的头文件的#include,但守卫会在第二次及以后的时间里启动,以确保编译器只看到一次内容。
编译器重新解析任何东西都没有关系;这就是它的工作。您只需提供一次内容,然后编译器就会看到它,并且可以根据需要再次引用它。
【讨论】: