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 的文字类型的静态数据成员 的相关文章

  • 结构化绑定中缺少类型信息

    我刚刚了解了 C 中的结构化绑定 但有一件事我不喜欢 auto x y some func is that auto正在隐藏类型x and y 我得抬头看看some func的声明来了解类型x and y 或者 我可以写 T1 x T2 y
  • 没有特殊字符的密码验证器

    我是 RegEx 的新手 已经进行了大量搜索 但没有找到任何具体内容 我正在编写一个验证密码字符串的正则表达式 可接受的字符串必须至少具有 4 种字符类型中的 3 种 数字 小写字母 大写字母 特殊字符 我对包含有一个想法 也就是说 如果这
  • 根据属性的类型使用文本框或复选框

    如果我有这样的结构 public class Parent public string Name get set public List
  • 在一个数据访问层中处理多个连接字符串

    我有一个有趣的困境 我目前有一个数据访问层 它必须与多个域一起使用 并且每个域都有多个数据库存储库 具体取决于所调用的存储过程 目前 我只需使用 SWITCH 语句来确定应用程序正在运行的计算机 并从 Web config 返回适当的连接字
  • 类型中的属性名称必须是唯一的

    我正在使用 Entity Framework 5 并且有以下实体 public class User public Int32 Id get set public String Username get set public virtual
  • 通过引用传递 [C++]、[Qt]

    我写了这样的东西 class Storage public Storage QString key const int value const void add item QString int private QMap
  • 如何在 Cassandra 中存储无符号整数?

    我通过 Datastax 驱动程序在 Cassandra 中存储一些数据 并且需要存储无符号 16 位和 32 位整数 对于无符号 16 位整数 我可以轻松地将它们存储为有符号 32 位整数 并根据需要进行转换 然而 对于无符号 64 位整
  • 机器Epsilon精度差异

    我正在尝试计算 C 中双精度数和浮点数的机器 epsilon 值 作为学校作业的一部分 我在 Windows 7 64 位中使用 Cygwin 代码如下 include
  • 如何从 Visual Studio 将视图导航到其控制器?

    问题是解决方案资源管理器上有 29 个项目 而且项目同时具有 ASP NET MVC 和 ASP NET Web 表单结构 在MVC部分中 Controller文件夹中有大约100个子文件夹 每个文件夹至少有3 4个控制器 视图完全位于不同
  • free 和 malloc 在 C 中如何工作?

    我试图弄清楚如果我尝试 从中间 释放指针会发生什么 例如 看下面的代码 char ptr char malloc 10 sizeof char for char i 0 i lt 10 i ptr i i 10 ptr ptr ptr pt
  • 从经典 ASP 调用 .Net C# DLL 方法

    我正在开发一个经典的 asp 项目 该项目需要将字符串发送到 DLL DLL 会将其序列化并发送到 Zebra 热敏打印机 我已经构建了我的 DLL 并使用它注册了regasm其次是 代码库这使得 IIS 能够识别它 虽然我可以设置我的对象
  • 如何使从 C# 调用的 C(P/invoke)代码“线程安全”

    我有一些简单的 C 代码 它使用单个全局变量 显然这不是线程安全的 所以当我使用 P invoke 从 C 中的多个线程调用它时 事情就搞砸了 如何为每个线程单独导入此函数 或使其线程安全 我尝试声明变量 declspec thread 但
  • 人脸 API DetectAsync 错误

    我想创建一个简单的程序来使用 Microsoft Azure Face API 和 Visual Studio 2015 检测人脸 遵循 https social technet microsoft com wiki contents ar
  • 结构体的内存大小不同?

    为什么第一种情况不是12 测试环境 最新版本的 gcc 和 clang 64 位 Linux struct desc int parts int nr sizeof desc Output 16 struct desc int parts
  • 空指针与 int 等价

    Bjarne 在 C 编程语言 中写道 空指针与整数零不同 但 0 可以用作空指针的指针初始值设定项 这是否意味着 void voidPointer 0 int zero 0 int castPointer reinterpret cast
  • 复制目录下所有文件

    如何将一个目录中的所有内容复制到另一个目录而不循环遍历每个文件 你不能 两者都不Directory http msdn microsoft com en us library system io directory aspx nor Dir
  • 为什么 isnormal() 说一个值是正常的,而实际上不是?

    include
  • 相当于Linux中的导入库

    在 Windows C 中 当您想要链接 DLL 时 您必须提供导入库 但是在 GNU 构建系统中 当您想要链接 so 文件 相当于 dll 时 您就不需要链接 为什么是这样 是否有等效的 Windows 导入库 注意 我不会谈论在 Win
  • MySQL Connector C/C API - 使用特殊字符进行查询

    我是一个 C 程序 我有一个接受域名参数的函数 void db domains query char name 使用 mysql query 我测试数据库中是否存在域名 如果不是这种情况 我插入新域名 char query 400 spri
  • Mono 应用程序在非阻塞套接字发送时冻结

    我在 debian 9 上的 mono 下运行一个服务器应用程序 大约有 1000 2000 个客户端连接 并且应用程序经常冻结 CPU 使用率达到 100 我执行 kill QUIT pid 来获取线程堆栈转储 但它总是卡在这个位置

随机推荐