【问题标题】:Template classes and include guards in C++C++ 中的模板类和包含守卫
【发布时间】:2011-01-24 23:10:55
【问题描述】:

在模板类周围包含守卫是否明智?

每次你用不同的实现引用模板类时,不应该重新解析它们吗?

N.B 在 Visual C++ 2008 中,将两者结合起来没有错误...

【问题讨论】:

    标签: c++ templates include-guards


    【解决方案1】:

    您需要包括警卫。考虑这段代码:

    // 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
    

    此外,包含模板的标头通常也包含非模板代码。

    【讨论】:

    • 严格来说这是一个模板函数而不是一个模板类,但原理是一样的——如果你两次声明同一个类,你会得到一个多重定义错误,模板与否。
    • 在这里查看我的答案 - stackoverflow.com/questions/22595015/…
    【解决方案2】:

    模板定义应该被解析一次(这里有两个阶段名称查找之类的东西,以便可以立即给出尽可能多的错误而无需实例化)。实例化是使用当时构建的内部数据结构完成的。

    模板定义通常(即,如果你不使用export 或做一些特殊的事情)在头文件中,应该有它们的包含保护。为模板定义添加一个无用但无害。

    【讨论】:

    • 始终添加包含保护,习惯它,因为这是一个很好的做法。
    • 如果您在 win32 上进行任何开发,请在使用包含守卫时包含 #pragma once
    • +1 表示实例化是使用第一次扫描时构建的内部数据结构完成的
    【解决方案3】:

    简短回答:您计划在任何定义中多次包含的每个单元都应该有一个标题保护。那是有或没有模板。

    【讨论】:

      【解决方案4】:

      回答您的第一个问题:是的,在模板类周围包含守卫是明智且强制性的。或者更严格地包围每个头文件的全部内容。

      当您在头文件中有内容时,这是遵守单一定义规则的方法,以便它可以共享并且仍然安全。可能还有其他头文件包括您的。当编译器编译一个模块文件时,它可能会多次看到你的头文件的#include,但守卫会在第二次及以后的时间里启动,以确保编译器只看到一次内容。

      编译器重新解析任何东西都没有关系;这就是它的工作。您只需提供一次内容,然后编译器就会看到它,并且可以根据需要再次引用它。

      【讨论】:

        猜你喜欢
        • 2012-01-19
        • 2019-04-25
        • 2017-07-31
        • 2013-06-22
        • 2022-01-22
        • 2017-11-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多