c++ - 编辑标题时处理编译时间

标签 c++ c++11

我正在从事一个大型项目,该项目使用一个系统,该系统在运行 make 时会生成一些头文件,其中包含一些在代码中随处使用的常量。由于该项目的大小,如果更改其中一个 header (删除常量或添加另一个常量),几乎整个项目都必须重新编译(有时需要几个小时)。

我最初的解决方案是编写某种 ConstantManager 类,它有一个包含每个代码值对的映射和一个返回给定代码的 getter 作为字符串返回它的值(非常简单) 并更改 header 生成器,以便它将常量定义为 #define,这些常量扩展为 ConstantManager 的实例和对 getter 的调用。这样做的问题是它不适用于 switch 语句(好吧...实际上是 case 语句),因为返回值不是常量表达式。

我的问题是:这个问题是否有任何替代解决方案或一些技巧可以使我的开关工作?

最佳答案

您可以将巨大的 header 拆分为较小的 header 并包含它们。这可能需要很多初始工作,但却是最直接的,并且可能与您当前的解决方案兼容。

另一种选择是创建使您的 ConstManager 类具有 constexpr 成员。为此,您不需要太多,但不能使用 map 。

ConstManager.h

namespace ConstManager {

  namespace detail {
    struct Constant {
      char const * const name;
      char const * const value;
    };


    Constant const * const constants;
    unsigned int total_variables;
  }

  inline char const * const ConstManager::get(char const * needle) constexpr {
    using namespace ConstManager::detail;
    /* i was not able to quickly find a constexpr compatible binary search function*/
    if(int i = 0;  i < total_variables; ++i){
      Constant & const c = constants[i];
      if(strcmp(c.name, needle) == 0){
        return c.value;
      }
    }
    return nullptr;
  }
}

ConstManager.c 应该生成

ConstManager::detail::Constant ConstManager::detail::constants [] = {
  {"first var", "first value"},
  {"second var", "second value"}
};

unsigned int ConstManager::detail::total_variables = 2;

提出的第一个解决方案(这是在第一次编辑之前):

我认为您应该用常规外部变量替换所有定义。

虽然有两个警告:

  1. 如果这些定义用于连接字符串,它将不起作用
  2. 对于编译器来说,如果不是不可能的话,它可能会使内联变得更加困难,但如果这很重要,只有分析器才能知道。

constmgr.h

  // make all your needed constansts externs
  namespace Constants {
    extern int const theFirstConstant;
    extern char const * const someStringConstant;
  }

然后在构建时生成源文件。

constexpr.cpp

 int const Constants::theFirstConstant = 1000;
 char const * const Constants::someStringConstant = "hihihoho";

关于c++ - 编辑标题时处理编译时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24140792/

相关文章:

c++ - 如何将模板存储为典型 C++ 类的成员

c++ - 泛型枚举和其他类型的重载模板函数

随机数生成器的 C++11 线程安全

c++ - 从 ‘void*’ 到 ‘void* (*)(void*)’ C++ 的无效转换?

c++ - 结构引用和取消引用运算符

c++ - 在动态加载的 dll 中查找名称错误的函数

c++ - 在 C++ 中将 unsetf 与十六进制十进制数和八进制数一起使用

C++ 非常简单的线程?

c++ - char* 到 char[]

c++ - 为什么 b.isEm() 在不同的行打印不同的东西?