静态 constexpr 类成员何时需要类外定义?

2024-03-23

我有以下 C++11 代码(简化版本):

struct Info
{
    const char * name;
    int version;
};

class Base
{
public:
    const Info info;
    Base (Info info) : info (info) {}
};

class Derived : public Base
{
public:
    static constexpr Info info = {"Foobar", 2};
    Derived () : Base (info) {}
};

int main ()
{
    static Derived derived;
    return 0;
}

GCC 4.9.1 可以很好地编译和链接此代码。另一方面,Clang 3.5.0 抱怨未定义的引用:

/tmp/test-109c5c.o: In function `main':
test.cc:(.text+0x1c): undefined reference to `Derived::info'
test.cc:(.text+0x22): undefined reference to `Derived::info'
clang: error: linker command failed with exit code 1 (use -v to see invocation)

哪个是对的?这段代码合法不合法?我对静态 constexpr 成员规则的理解(主要基于这个问题 https://stackoverflow.com/questions/22027228/c-static-constexpr-member-redeclaration-outside-of-class)是只有当获取变量的地址时才需要类外定义。但我不会获取 Derived::info 的地址或在任何地方使用对其的引用;我只是将其按值传递给 Base 构造函数。

我发现的各种解决方法:

  • 将两个构造函数(基类和派生类)设置为 constexpr。这可能是也可能不是真实类的选项,真实类比示例中的类更复杂。无论如何,我要尝试一下。
  • 在 main 中声明 Derived 实例,并使用自动持续时间而不是静态持续时间。这不是实际项目的选项:派生类是一个插件实现,需要将其实例导出为共享对象中的公共符号。
  • 完全删除 Derived::info 并使用大括号初始化的临时对象调用 Base 构造函数,即Base ({"Foobar", 2})。这个解决方案可以工作,但随着更多成员被添加到 struct Info 中,它会变得丑陋(在我看来)。

啊哈,看来问题是隐含的Info(const Info &)复制构造函数。为了通过const Info &引用该构造函数,需要获取 Derived::info 的地址。

显然,GCC 在优化复制构造函数方面比 Clang 更积极。如果我使用-fno-elide-constructors,然后 GCC 还抱怨对 Derived::info 的未定义引用。

无论如何,将 Base 和 Derived 构造函数声明为 constexpr 似乎完成了我想要在这里发生的事情,即在编译时初始化 Base::info,而不是在运行时从单独的 Derived::info 复制。

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

静态 constexpr 类成员何时需要类外定义? 的相关文章

  • 如何将 std::string& 转换为 C# 引用字符串

    我正在尝试将 C 函数转换为std string参考C 我的 API 如下所示 void GetStringDemo std string str 理想情况下 我希望在 C 中看到类似的东西 void GetStringDemoWrap r
  • STL 迭代器:前缀增量更快? [复制]

    这个问题在这里已经有答案了 可能的重复 C 中的预增量比后增量快 正确吗 如果是 为什么呢 https stackoverflow com questions 2020184 preincrement faster than postinc
  • C# 异步等待澄清?

    我读了here http blog stephencleary com 2012 02 async and await html that 等待检查等待的看看它是否有already完全的 如果 可等待已经完成 那么该方法将继续 运行 同步
  • 如何在 Cassandra 中存储无符号整数?

    我通过 Datastax 驱动程序在 Cassandra 中存储一些数据 并且需要存储无符号 16 位和 32 位整数 对于无符号 16 位整数 我可以轻松地将它们存储为有符号 32 位整数 并根据需要进行转换 然而 对于无符号 64 位整
  • C++11 删除重写方法

    Preface 这是一个关于最佳实践的问题 涉及 C 11 中引入的删除运算符的新含义 当应用于覆盖继承父类的虚拟方法的子类时 背景 根据标准 引用的第一个用例是明确禁止调用某些类型的函数 否则转换将是隐式的 例如最新版本第 8 4 3 节
  • 传递给函数时多维数组的指针类型是什么? [复制]

    这个问题在这里已经有答案了 我在大学课堂上学习了 C 语言和指针 除了多维数组和指针之间的相似性之外 我认为我已经很好地掌握了这个概念 我认为由于所有数组 甚至多维 都存储在连续内存中 因此您可以安全地将其转换为int 假设给定的数组是in
  • 如何使从 C# 调用的 C(P/invoke)代码“线程安全”

    我有一些简单的 C 代码 它使用单个全局变量 显然这不是线程安全的 所以当我使用 P invoke 从 C 中的多个线程调用它时 事情就搞砸了 如何为每个线程单独导入此函数 或使其线程安全 我尝试声明变量 declspec thread 但
  • 对类 static constexpr 结构的未定义引用,g++ 与 clang

    这是我的代码 a cp p struct int2 int x y struct Foo static constexpr int bar1 1 static constexpr int2 bar2 1 2 int foo1 return
  • 人脸 API DetectAsync 错误

    我想创建一个简单的程序来使用 Microsoft Azure Face API 和 Visual Studio 2015 检测人脸 遵循 https social technet microsoft com wiki contents ar
  • 如何获取 EF 中与组合(键/值)列表匹配的记录?

    我有一个数据库表 其中包含每个用户 年份组合的记录 如何使用 EF 和用户 ID 年份组合列表从数据库获取数据 组合示例 UserId Year 1 2015 1 2016 1 2018 12 2016 12 2019 3 2015 91
  • 结构体的内存大小不同?

    为什么第一种情况不是12 测试环境 最新版本的 gcc 和 clang 64 位 Linux struct desc int parts int nr sizeof desc Output 16 struct desc int parts
  • C# - 当代表执行异步任务时,我仍然需要 System.Threading 吗?

    由于我可以使用委托执行异步操作 我怀疑在我的应用程序中使用 System Threading 的机会很小 是否存在我无法避免 System Threading 的基本情况 只是我正处于学习阶段 例子 class Program public
  • 如何定义一个可结构化绑定的对象的概念?

    我想定义一个concept可以检测类型是否T can be 结构化绑定 or not template
  • x:将 ViewModel 方法绑定到 DataTemplate 内的事件

    我基本上问同样的问题这个人 https stackoverflow com questions 10752448 binding to viewmodels property from a template 但在较新的背景下x Bind V
  • C# xml序列化必填字段

    我需要将一些字段标记为需要写入 XML 文件 但没有成功 我有一个包含约 30 个属性的配置类 这就是为什么我不能像这样封装所有属性 public string SomeProp get return someProp set if som
  • LINQ:使用 INNER JOIN、Group 和 SUM

    我正在尝试使用 LINQ 执行以下 SQL 最接近的是执行交叉联接和总和计算 我知道必须有更好的方法来编写它 所以我向堆栈团队寻求帮助 SELECT T1 Column1 T1 Column2 SUM T3 Column1 AS Amoun
  • 在 WPF 中使用 ReactiveUI 提供长时间运行命令反馈的正确方法

    我有一个 C WPF NET 4 5 应用程序 用户将用它来打开某些文件 然后 应用程序将经历很多动作 读取文件 通过许多插件和解析器传递它 这些文件可能相当大 gt 100MB 因此这可能需要一段时间 我想让用户了解 UI 中发生的情况
  • C# 使用“?” if else 语句设置值这叫什么

    嘿 我刚刚看到以下声明 return name null name NA 我只是想知道这在 NET 中叫什么 是吗 代表即然后执行此操作 这是一个俗称的 条件运算符 三元运算符 http en wikipedia org wiki Tern
  • Mono 应用程序在非阻塞套接字发送时冻结

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

    我有两个控制器 一个mvc控制器和一个api控制器 它们都在同一个项目中 HomeController Controller DataController ApiController 如果我想从 HomeController 中使用 Dat

随机推荐

  • 为什么在android中的输入流之后要关闭OutputStream

    我正在以这种方式从 android 连续调用我的 servlet 两次 FIRST CONNECTION URL url new URL http 172 16 32 160 8080 xyz check availability Http
  • 安排 Google Cloud Dataflow 作业的最简单方法

    我只需要每天运行一个数据流管道 但在我看来 像 App Engine Cron Service 这样需要构建整个 Web 应用程序的建议解决方案似乎有点太多了 我正在考虑仅从 Compute Engine Linux 虚拟机中的 cron
  • 使用 C++ 中的标准流的灵活记录器类

    我想创建一个灵活的记录器类 我希望它能够将数据输出到文件或标准输出 另外 我想使用流 该类应该类似于 class Logger private std ostream m out or ofstream iostream i don t k
  • 在此 dnvm.ps1 命令中哪些参数显示未定义?结果部署到 Azure 网站失败

    我一直在 Linux 上开发一个新的 ASP NET 5 MVC 6 网站 我正在将 Git 与 Azure 结合使用 并且已经能够成功将其推送到 SCM 然而 由于一些未定义的参数 我的部署失败了 希望有人能告诉我终端输出中显示的命令中未
  • 如何使用 pythonnet 在 python 侦听器中订阅 .NET 事件?

    我正在尝试创建一个事件侦听器来订阅tick使用 Python 的外汇交易应用程序的 价格 事件 原始应用程序是一个本机 32 位 Windows 应用程序 名为元交易者4 这没有任何 API 所以mtapi https github com
  • 返回修改后的类和使用 type() 之间的区别

    我想这更像是一个 python 问题 而不是 django 问题 但我无法在其他地方复制这种行为 所以我将使用无法按预期工作的确切代码 当我发现这个工厂函数片段时 我正在 django 中处理一些动态表单 def get employee
  • GitHub Copilot - 请登录 github 并重试

    对于 Intellij 插件 GitHub Copilot 显示错误please login to github and try again 我已经完成了以下操作 使用我的 GitHub 用户和密码对 GitHub Copilot 进行了身
  • Swift UITableViewCell 对齐

    我正在尝试显示如下页面 页面标题 左对齐 区域名称 中心对齐 该地区的人 详细标签中带有电子邮件的副标题 但是 如果我选择副标题作为单元格样式 则所有内容都将左对齐 并且我无法在代码中更改它们 然后 如果我选择自定义作为样式 则详细文本标签
  • 当尝试在 R 中运行 kNN 时,我收到由 coercionNAs 引入的错误 NAs?

    我正在尝试在数据集上运行 kNN 但我不断收到一些 NA 错误 我已经用尽了堆栈溢出试图找到这个问题的解决方案 我在任何地方都找不到任何有用的东西 这是我正在使用的数据集 https www kaggle com tsiaras uk ro
  • java.util.Vector - 替代品

    以前 当长度未知时 我一直认为 Vector 适合用于非描述性对象 据我所知 我认为它也是线程安全的 什么会改变这一点Vector不应再使用 有什么替代方案 你应该使用ArrayList代替Vector Vector使用内部同步 但这对于实
  • Android - 如何拦截“安装应用程序”意图

    好吧 所以不完全确定这是可能的 但尝试编写一个应用程序 以便我可以在执行以下任何活动之前运行一些代码 1 从网络下载 APK 并启动安装程序 2 在android市场上按下安装按钮 是否有可能拦截并提示这些事件 或者谷歌已经将这些东西锁定得
  • 如何在 css URL 中使用相对/绝对路径?

    我有一个生产和开发服务器 问题是目录结构 发展 http dev com subdir images image jpg http dev com subdir resources css style css 生产 http live co
  • 通过进程 ID 将 KeyEvent 发送到目标窗口

    我需要创建一个关键事件 cmd r 用于刷新浏览器窗口 并传递我尝试定位的窗口的进程 ID 比方说 let customEvent NSEvent keyEvent with NSEvent EventType keyUp location
  • 表达式集子集化

    我有一个ExpressionSet我想要子集的对象 例如 gt str ESet Formal class ExpressionSet package Biobase assayData phenoData STATUS num 1 210
  • 在python中将JSON存储到数据库中

    我定期从 API 获取一些数据 并希望将 JSON 数据存储到数据库中以便稍后访问和使用 从 API 中 我每次都会获取此样本中的数据 data cursor null files nodes u code u BOPhmYQg5Vm u
  • CLLocation距离位置(在Swift中?)

    有人可以帮我将以下 Objective C 语句转换为 Swift 吗 CLLocationDistance distance fromLocation distanceFromLocation toLocation 我知道做到这一点一定很
  • 标准库类型的赋值运算符的 ref 限定符

    我想知道 标准类型的赋值运算符没有左值引用限定是否有原因 他们都不是 因此 我们可以这样写 std string 42 std string s hello std string world oops std vector
  • 在jgit中配置known_hosts

    使用 jgit 和 gitolite 进行源代码控制 我有一个应用程序 可以根据命令生成某些代码 并且我们希望将其提交给源代码控制 目标是快速拉动 提交新代码 然后推送它 我有以下方法 private void commitToGitRep
  • 为什么 ISO/IEC 对 C 和 C++ 标准收费而不是免费提供?

    ISO C 标准 ISO IEC 9899 和 ISO C 标准 ISO IEC 14882 未在线发布 相反 人们必须购买每一项标准的 PDF 版本 我想知道这背后的基本原理是什么 对于 C 和 C 编程语言来说 这些语言的权威规范不能免
  • 静态 constexpr 类成员何时需要类外定义?

    我有以下 C 11 代码 简化版本 struct Info const char name int version class Base public const Info info Base Info info info info cla