源文件全局作用域中的constexpr变量

3

在源文件中声明constexpr常量的正确方法是什么?我有两种方式:

constexpr int ORDER = 1;

vs

namespace {
constexpr int ORDER = 1;
} // unnamed namespace

我对将内容包装成未命名的命名空间的有用性提出质疑,原因是在全局范围内,constexpr 意味着 static。因此类似于头文件中写入的方式,我们可以使用 inline constexpr 来避免多个定义引起的问题。
static constexpr int ORDER = 1;

假设相同的规则应该适用于源文件,因此在源文件中声明的"constexpr变量"应该保证具有内部链接性,这使得static只是一个重复。

这是真的吗?还有其他建议吗?


2
命名空间在C++中是首选的。Static关键字指定变量的生命周期。 静态constexpr变量必须在编译时设置,因为它的生命周期是整个程序。 如果没有static关键字,编译器不一定要在编译时设置该值,并且可能决定稍后设置它。 PS:我会将这些常量包装在结构中。 - Martin.Martinsson
@Martin.Martinsson:constexpr 绝对需要编译时初始化(尽管像往常一样,as-if 可以做很多事情)。 - Davis Herring
在头文件中,你应该使用 inline 而不是未命名的命名空间或 static - Davis Herring
@DavisHerring 我增加了一个悬赏以吸引更多人关注这个问题。你同意现有的答案吗?你想贡献一个不同的答案吗? - Lorah Attkins
@LorahAttkins:这里的答案很好:我只是评论了标题大小写,因为它更重要。 - Davis Herring
1个回答

2
在源文件中声明的constexpr变量不需要放在未命名的命名空间中。由于最终目标是实现内部连接,您需要记住这个

属于命名空间范围的实体的名称如果是以下之一,则具有内部链接性:

  • 显式声明为静态变量、变量模板、函数或函数模板; 或
  • 非易失性const限定类型的非模板变量,除非
    • 它被显式声明为extern,或
    • 它是内联的或已导出的,或
    • 它曾经被先前声明,并且先前的声明没有内部链接性;或
  • 匿名联合体的数据成员。
constexpr暗示const而命名空间作用域上的const暗示具有内部链接” ,因此说这是多余的。
static constexpr int ORDER = 1;

甚至可以
namespace {
  static constexpr int ORDER = 1;
}

如果您想要实体证明内部链接属性,请考虑这个编译错误。它与此问题有关。

话虽如此,把你的单一定义的内部链接变量放在命名空间中也不会有任何损失,反而可以提高代码的结构性。 - 303

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接