【问题标题】:Smarter include guard in C++ to include headers several times inside different namespacesC++ 中更智能的包含保护可在不同的命名空间中多次包含标头
【发布时间】:2020-04-03 13:01:47
【问题描述】:

我需要一种方法来更好地使用 C++ 保护 #include

当同一个标题被包含两次时,第二个#include应该被忽略(这很简单):

#include "header1.hpp"
#include "header2.hpp"
#include "header1.hpp" //Should be ignored

但是当嵌套命名空间中包含相同的标头时,应该再次包含它(但每个命名空间不超过一次):

#include "header1.hpp"
#include "header2.hpp"

namespace foo_namespace {
    //May be this one is needed?
    #define NAMESPACE_ID foo_namespace

    #include "header1.hpp" //Should be included again
    #include "header1.hpp" //Should be ignored

    #undef NAMESPACE_ID
};

问题是:我应该如何保护header1.hpp里面的代码? 额外的要求是守卫本身应该是可重用的(定义为宏),因为我有很多应该以这种方式保护的标头。

【问题讨论】:

  • 我想知道为什么你需要一个文件被包含两次?
  • 我需要所有结构和功能的两个版本。第一个版本使用double 浮点数据类型,第二个版本使用float 浮点数据类型。
  • 您是否考虑过使用模板来确定数据类型?那么你不必有两次代码。
  • 然后我需要为所有东西制作模板。而且,除了数据类型之外,这些头包含的内容可能还有其他细微差别,例如在一个版本中删除了构造函数,在其他版本中缺少一些函数等。
  • 我知道我可以将标题中的每个类和每个函数以及每个 typedef 作为依赖于<bool VERSION> 的模板,然后添加 SFINAE 和其他模板魔法来禁用或修改数据类型和函数在VERSION。但我决定改为使用嵌套命名空间,并在 #include 之前第二次包含标题以及一些额外的 typedefs 和 #defines。

标签: c++ macros namespaces include preprocessor


【解决方案1】:

一个不错的解决方案是有一个没有保护的标题版本:

// header_noguard.hpp
// the declarations ...


// header.hpp
#pragma once // or a macro of your choice
#include "header_noguard.hpp"

// header_namespace.hpp
#pragma once // or a macro of your choice
namespace foo_namespace {
    #include "header_noguard.hpp"
};

现在,您可以多次添加header.hppheader_namespace.hpp。每个都防止多重包含,但都包含在各自命名空间中的声明。

【讨论】:

    猜你喜欢
    • 2013-11-13
    • 1970-01-01
    • 2011-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-26
    • 1970-01-01
    相关资源
    最近更新 更多