constexpr 定义声明为 const 的文字类型的静态数据成员

2023-12-02

我有一个关于 constexpr 定义在类定义中声明为 const (且未指定内联或 constexpr)的文字类型静态数据成员的问题:

// S.h

struct S
{
  static int const i; // not specified inline or constexpr
};

// S.cpp

#include "S.h"
constexpr int const S::i = 42; // definition, not declaration

//主.cpp

#include "S.h"
int main()
{
  return S::i;
}

Clang/gcc 在 C++11/14 模式下返回 42,但在 C++17 模式下报告错误(对 S::i 的未定义引用)。如果我注释掉 constexpr,它们也会在 C++17 模式下返回 42。

S::i 具有外部链接,因为 S 具有外部链接。 S::i 未声明为 constexpr,因此(如果我没有记错的话)C++17 10.1.5 p1 不适用:

使用 constexpr 声明的函数或静态数据成员 说明符隐式是内联函数或变量

我理解这句话的意思好像是(加粗我的理解): 使用 constexpr 说明符声明的静态数据成员在类定义中隐式是一个内联变量

因此 S::i 不是内联变量。 然而 S::i 的定义似乎在 C++17 模式下具有内部链接,就好像 constexpr 意味着内联一样。它是否正确?如果是这样,标准中的证据在哪里?

还是我误解了 10.1.5 p1 它的真正含义(粗体显示我的误解): 使用 constexpr 说明符声明的静态数据成员在类定义和命名空间范围内的定义是隐式的内联变量吗?


[dcl.内联]/6 states:

如果具有外部链接的函数或变量被声明为内联 一个翻译单元,应在所有翻译中声明为内联 它出现的单位;无需诊断。

所以正如你所指出的,if我们可以证明constexpr隐含地暗示inline,它将解释您的示例的未定义​​引用错误。

[dcl.constexpr]/1国家[强调我的]:

应应用 constexpr 说明符只针对定义的 变量或变量模板或函数的声明或 函数模板。

也:

使用 constexpr 说明符声明的函数或静态数据成员 隐式是一个内联函数或变量([dcl.内联]).

[基本.def]/1国家[强调我的]:

声明可以将一个或多个名称引入翻译单元或重新声明先前声明引入的名称.

以及 (/2):

声明是定义,除非:

[...没有一个适用于constexpr int const S::i = 42;]

这里的本质是定义是声明(完全定义了声明引入的实体),所以constexpr int const S::i = 42;(除了作为定义之外)也是一个(重新)声明,在这种情况下 [dcl.constexpr]/1 适用,并且S::i内联在翻译单元中S.cpp,因此,由 [dcl.inline]/6,在它出现的所有其他翻译单元中。相反,通过 [dcl.constexpr]/1,constexpr说明符,例如特别是在静态数据成员的上下文中,只能出现在定义的声明中。

与后者的情况有些相关的是,constexpr从 C++17 开始,带初始化的静态数据成员声明也是一个定义,允许以下规范:constexpr只能应用于变量定义(即,永远不会应用于非初始化声明)。看[depr.static_constexpr]/1.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

constexpr 定义声明为 const 的文字类型的静态数据成员 的相关文章

  • 结构体如何存储在内存中?

    我有一个struct iof header在我的代码中 我确定它的宽度是 24 字节 我执行 sizeof iof header 它返回 32 字节宽 问题1为什么是 32 字节宽而不是 24 字节宽 问题2包括其成员在内 结构体如何存储在
  • 将公历日期转换为儒略日期,然后再转换回来(随着时间)

    我正在编写一个程序 必须将当前的公历日期和时间转换为儒略日期 然后再转换回公历门 最终我需要添加能够添加年 月 日 小时 分钟和秒的功能 但我需要先解决这部分问题 现在我已经从公历日期转换为儒略日期 所以从逻辑上讲 我觉得我应该能够以某种方
  • 局部函数声明有什么用处吗?

    大多数像我这样的 C 程序员都曾犯过以下错误 class C int main C c declares a function c taking no arguments returning a C not as intended by m
  • C# 无法捕获 SerializationException

    我的程序在加载序列化文件的部分遇到问题 如果文件无法反序列化 我希望很好地失败 但由于某种原因 我的程序将中断而不是进入 catch 子句 这是我的代码 using FileStream fs new FileStream openFile
  • 组合框下拉位置

    我有一个最大化的表单 其中包含 500px 的组合框控件 停靠在右上角 Width 尝试打开组合框后 列表的一半超出了屏幕 如何强制列表显示在表单中 棘手的问题 我找不到解决这个问题的好办法 只是一个解决方法 添加一个新类并粘贴如下所示的代
  • 无法加载程序集问题

    我收到以下错误 无法加载程序集 错误详细信息 System BadImageFormatException 无法加载文件或程序集 文件 或其依赖项之一 该程序集是由比当前加载的运行时更新的运行时构建的 无法加载 该程序集是使用 Net Fr
  • 在c#中获取没有时间的日期

    我的表上有一列 缺勤日期时间 日期 当我想要获取包含日期的行时 它返回 0 行 这是我的 C 代码 DateTime ClassDate DateTime Parse lblDate Content ToString var Abs dbs
  • 我在使用 ado.net 时收到错误 Argument 2 may not be pass with ref keywords

    int t 0 cmd Parameters AddWithValue Res ref t 我在第二行收到错误 参数 2 不能与 ref 关键字一起传递 您只能通过引用传递参数ref if the 范围 is a ref参数也是如此 Add
  • 如何从外语线程调用Python函数(C++)

    我正在开发一个程序 使用 DirectShow 来抓取音频数据 媒体文件 DirectShow 使用线程将音频数据传递给回调 我的程序中的函数 然后我让该回调函数调用另一个函数 Python 中的函数 我使用 Boost Python 来包
  • 使用数据绑定,如何将包含表情符号的文本绑定到标签并使其正确显示?

    我正在编写一个应用程序来连接 WordPress BuddyPress API 该应用程序将允许用户通过 API 相互发送消息 当这些消息包含表情符号时 我很难正确显示它们 以下是 API 返回的消息文本的简短示例 Hi x1f642 ho
  • 当需要不同数量和类型的参数时如何创建操作委托列表

    我们有一组大约两打的类 它们继承自具有抽象 Validate 方法的基类 当然 每个类都有不同的验证需求 但它们之间的不同组合需要规则 因此 正如您可以想象的那样 这导致了大量代码重复 例如 A 类需要规则 1 3 6 和 9B 类需要规则
  • C#:自定义转换为值类型

    是否可以将自定义类转换为值类型 这是一个例子 var x new Foo var y int x Does not compile 是否有可能实现上述情况 我需要超载一些东西吗Foo 您将必须重载强制转换运算符 public class F
  • DataGridView 行背景颜色没有改变

    我想根据加载时的特定条件更改 DGV 行的背景颜色 即使在 Windows 窗体中也是如此 但我看不到任何 DGV 行的颜色有任何变化 谁能告诉我如何解决这个问题 private void frmSecondaryPumps Load ob
  • Gremlin.net 文本包含等效项

    我正在使用 Gremlin net 库连接到 janus 图形服务器 我使用 cassandra 和弹性搜索进行数据存储和索引 在我使用的 gremlin 语言和 gremlin 控制台中文本包含在属性的文本中进行搜索 我正在使用混合索引
  • Type.GetInterfaces() 仅适用于声明的接口

    首先 像这样的问题有很多 也许有些OP甚至在问同样的问题 问题是这些问题的答案 无论是否接受 都没有真正回答这个问题 至少我找不到 如何确定类直接声明的接口 而不是由父级或声明的接口继承的接口 e g interface I interfa
  • 如何同步nosql db(ravendb)中的更改

    我已经开始在 RavenDB 的示例上学习 NoSQL 我从一个最简单的模型开始 假设我们有由用户创建的主题 public class Topic public string Id get protected set public stri
  • 选择合适的IDE

    您会推荐使用以下哪种 IDE 语言来在 Windows 下开发涉及识别手势并与操作系统交互的项目 我将使用 OpenCV 库来执行图像处理任务 之后 我将使用 win32 API 或 NET 框架与操作系统交互 具体取决于您建议的工具 性能
  • “1个未解决的外部”C++

    我已经检查了所有文件之间的连接以及类和函数定义 但每次我尝试运行我的程序时 它都会阻止我并告诉我它有 1 个未解析的外部 该程序应该打开多个文件 一个 学生 文件和一个 成绩 文件 从中读取数据 然后使用 查询文件 来查找数据 找到查询中要
  • 为什么在构造函数中设置字段是(或不是)线程安全的?

    假设您有一个像这样的简单类 class MyClass private readonly int a private int b public MyClass int a int b this a a this b b public int
  • 使用 CodeDOM 将程序集添加到 BuildManager 会导致间歇性错误

    我正在使用 CodeDOM 在运行时创建内存中程序集 如下所示 public Assembly Compile CodeCompileUnit targetUnit string path Path GetDirectoryName new

随机推荐