【问题标题】:'Constexpr' vs 'extern const'. Which has priority?“constexpr”与“extern const”。哪个优先?
【发布时间】:2016-08-11 07:48:24
【问题描述】:

何时使用constexpr,何时使用extern const

我有这样的情况:

  • 在标题(.h)中:

    extern const int MAX_NUMBER_OF_ROWS;
    
  • 在源代码 (.cpp) 中:

    const int MAX_NUMBER_OF_ROWS= 99;
    

文件(头文件和源文件)仅包含此类定义和声明。

是否建议只使用头文件中的constexpr 并去掉源文件,就像这里一样?:

// this is in the header file. There is no cpp file any more.
constexpr int MAX_NUMBER_OF_ROWS= 99;

【问题讨论】:

  • 这些是正交的——你总是可以在标题中使用const int MAX_NUMBER_OF_ROWS = 99;;然后问题是是否将const 更改为constexpr。通常只有在包含标头时不知道该值的情况下才能按照您的方式使用它
  • 好的,如果按照你说的在header里面,可以是constexpr吧?

标签: c++ c++11 constants extern constexpr


【解决方案1】:

在头文件中使用extern const 只会告诉编译器该变量存在且不可修改。它不会告诉编译器它的值,这意味着它不再是编译时常量。如果它不是编译时常量,则不能用于例如case 或作为数组大小。

正如MM在评论中所说,要么使用

const int MAX_NUMBER_OF_ROWS= 99;

constexpr int MAX_NUMBER_OF_ROWS= 99;

直接在头文件中,它将是包含头文件的所有翻译单元中的编译时常量。

【讨论】:

  • 现在的问题是:什么时候在头文件中使用const int,什么时候使用constexpr int
  • 在 C 中,如果您在标头中执行纯 const int MAX_NUMBER_OF_ROWS= 99; 并将其包含在多个源文件中,则会出现链接错误。这在 C++ 中是否有所不同,还是您的答案中缺少这一点?
  • @user694733 是的,它在 C++ 中是不同的; const 变量具有内部链接,除非使用 extern 声明(在定义中,或在同一变量的先前声明中)
  • @mtb 这更多的是个人喜好问题,而不是其他任何事情。唯一不是这样的情况是,如果您的目标是不支持 C++11 的旧编译器。
  • In C++>=17 constexpr 生成变量 constexpr inline,从而消除 ODR 问题。
【解决方案2】:

extern const 如果您计划将来将变量初始化为不同的值,并且不希望重新编译使用此变量的代码,则可以使用。 (我从未见过这种需求,但在某些情况下它可能有用。)正如其他人所说,这个变量的值不能用于常量表达式。

constexpr 可以在编译时知道变量的值时使用。

【讨论】:

  • 一个很好的例子是版本字符串。如果你使用 cmake 将当前的 git 版本写入程序,它会一直改变,所以不要在标题中
【解决方案3】:

如果你的编译器支持,constexpr 会更好。

它在编译时评估函数或变量的值,具有更好的性能(更少的内存查找和读取)和更少的内存成本(不存在于数据部分中)。

但有些编译器不支持它,例如 Visual Studio 2013 或更早版本。

【讨论】:

    猜你喜欢
    • 2011-11-09
    • 2017-04-28
    • 2015-05-04
    • 2023-03-15
    • 2014-03-10
    • 1970-01-01
    • 1970-01-01
    • 2016-07-24
    • 2011-11-14
    相关资源
    最近更新 更多