noexcept 在派生类中的用法

2024-02-15

我在使用时遇到问题noexcept派生类上的说明符,更准确地说,当父类是抽象类时(具有protected构造函数)。

以下是我声明类的方式的示例。

  • With a public基类中的构造函数:一切正常。
  • 与相同的代码protected并且派生类不再是“不可抛出可移动的”。

我错过了什么吗?是std::is_nothrow_move_constructible在派生类声明中使用的正确特征还是我应该使用其他东西?

#include <cstdlib>
#include <iostream>

class BaseOk
{
public:
    BaseOk ( BaseOk&& other ) noexcept {}
};

class BaseNok
{
protected:
    BaseNok ( BaseNok&& other ) noexcept {}
};

class ChildOk : public BaseOk
{
public:
    ChildOk ( ChildOk&& other ) noexcept ( std::is_nothrow_move_constructible < BaseOk >::value )
        : BaseOk ( std::move ( other ) ) {}
};

class ChildNok : public BaseNok
{
public:
    ChildNok ( ChildNok&& other ) noexcept ( std::is_nothrow_move_constructible < BaseNok >::value )
        : BaseNok ( std::move ( other ) ) {}
};

int main ()
{
    std::cout << std::boolalpha;
    std::cout << "Is BaseOk   move constructible?         " << std::is_move_constructible < BaseOk >::value << '\n';
    std::cout << "Is ChildOk  move constructible?         " << std::is_move_constructible < ChildOk >::value << '\n';

    std::cout << '\n';
    std::cout << "Is BaseOk   nothrow move constructible? " << std::is_nothrow_move_constructible < BaseOk >::value << '\n';
    std::cout << "Is ChildOk  nothrow move constructible? " << std::is_nothrow_move_constructible < ChildOk >::value << '\n';

    std::cout << '\n';
    std::cout << "Is BaseNok  move constructible?         " << std::is_move_constructible < BaseNok >::value << '\n';
    std::cout << "Is ChildNok move constructible?         " << std::is_move_constructible < ChildNok >::value << '\n';

    std::cout << '\n';
    std::cout << "Is BaseNok  nothrow move constructible? " << std::is_nothrow_move_constructible < BaseNok >::value << '\n';
    std::cout << "Is ChildNok nothrow move constructible? " << std::is_nothrow_move_constructible < ChildNok >::value << '\n';
    std::cout << std::endl;

    return EXIT_SUCCESS;
}

Output:

 Is BaseOk   move constructible?         true
 Is ChildOk  move constructible?         true

 Is BaseOk   nothrow move constructible? true
 Is ChildOk  nothrow move constructible? true

 Is BaseNok  move constructible?         false
 Is ChildNok move constructible?         true

 Is BaseNok  nothrow move constructible? false
 Is ChildNok nothrow move constructible? false

___ 编辑 ____________________________________________________________

经过一段时间的搜索,并考虑到答案奥列格·波格丹诺夫,不幸的是似乎无法结合protected构造函数使用noexcept ( is_nothrow_... ).

我正在编写抽象类和声明的构造函数protected仅用于文档目的。现在,建设者又回到了public但我面临另一个问题:

由于抽象类无法实例化,std::is_nothrow_move_constructible<BaseClass>回报false并且所有派生类永远不能被标记为不抛出异常,即使它们没有抛出异常。

请参阅下面的示例:

#include <cstdlib>
#include <iostream>

class Foo
{
public:
    Foo ( Foo&& other ) noexcept {}
    virtual ~Foo () = 0;  // Removing '= 0' makes both outputs print 'true'.
};
Foo::~Foo () {}

class Bar : public Foo
{
public:
    Bar ( Bar&& other ) noexcept ( std::is_nothrow_move_constructible < Foo >::value )
        : Foo ( std::move ( other ) ) {}
};

int main ()
{
    std::cout << std::boolalpha;
    std::cout << "Foo: " << std::is_nothrow_move_constructible < Foo >::value << '\n';
    std::cout << "Bar: " << std::is_nothrow_move_constructible < Bar >::value << '\n';

    return EXIT_SUCCESS;
}

Output:

Foo: false
Bar: false

当评价为true is_move_constructible http://en.cppreference.com/w/cpp/types/is_move_constructible工作原理完全一样是可构造的 http://en.cppreference.com/w/cpp/types/is_constructible,这反过来又说明了

T 是对象或引用类型并且变量定义 T obj(std::declval()...);是格式良好的

我的猜测是,在你的情况下,定义BaseNok obj(...)不是真的格式良好的,因为你既没有公共默认构造函数(它被隐式删除),也没有任何其他可访问构造函数(受保护的构造函数不是),因此它的评估结果为false。 (定义健康状况虽然它本身是有争议的)

ChildNok 仍然是 move_constructible,因为您将其 move ctor 公开,其他情况下评估为false正是因为std::is_move_constructible < BaseNok >::value已经false


编辑: 至于编辑过的问题,note的部分是可构造的 http://en.cppreference.com/w/cpp/types/is_constructible提及

在许多实现中,is_nothrow_constructible 还会检查析构函数是否抛出,因为它实际上是 noexcept(T(arg))

当您将析构函数保持为纯虚拟时,它可能无法通过检查。

我个人不确定这是疏忽还是类型特征的设计,有些问题包含在LWG第2116期 http://cplusplus.github.io/LWG/lwg-active.html#2116

我在这里并不是提出可扩展的解决方案,但是既然基类也是 noexcept(),为什么现在不无条件地将派生类标记为 no except

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

noexcept 在派生类中的用法 的相关文章

  • 通过引用传递 [C++]、[Qt]

    我写了这样的东西 class Storage public Storage QString key const int value const void add item QString int private QMap
  • std::vector 与 std::stack

    有什么区别std vector and std stack 显然 向量可以删除集合中的项目 尽管比列表慢得多 而堆栈被构建为仅后进先出的集合 然而 堆栈对于最终物品操作是否更快 它是链表还是动态重新分配的数组 我找不到关于堆栈的太多信息 但
  • 随着时间的推移,添加到 List 变得非常慢

    我正在解析一个大约有 1000 行的 html 表 我从一个字符串中添加 10 个字符串 td 每行到一个list td
  • 如何连接重叠的圆圈?

    我想在视觉上连接两个重叠的圆圈 以便 becomes 我已经有部分圆的方法 但现在我需要知道每个圆的重叠角度有多大 但我不知道该怎么做 有人有主意吗 Phi ArcTan Sqrt 4 R 2 d 2 d HTH Edit 对于两个不同的半
  • 如何在 C++ 中标记字符串?

    Java有一个方便的分割方法 String str The quick brown fox String results str split 在 C 中是否有一种简单的方法可以做到这一点 The 增强分词器 http www boost o
  • 无限循环与无限递归。两者都是未定义的吗?

    无副作用的无限循环是未定义的行为 看here https coliru stacked crooked com view id 24e0a58778f67cd4举个例子参考参数 https en cppreference com w cpp
  • 用于 FTP 的文件系统观察器

    我怎样才能实现FileSystemWatcherFTP 位置 在 C 中 这个想法是 每当 FTP 位置添加任何内容时 我都希望将其复制到我的本地计算机 任何想法都会有所帮助 这是我之前问题的后续使用 NET 进行选择性 FTP 下载 ht
  • 访问外部窗口句柄

    我当前正在处理的程序有问题 这是由于 vista Windows 7 中增强的安全性引起的 特别是 UIPI 它阻止完整性级别较低的窗口与较高完整性级别的窗口 对话 就我而言 我想告诉具有高完整性级别的窗口进入我们的应用程序 它在 XP 或
  • 方程“a + bx = c + dy”的积分解

    在等式中a bx c dy 所有变量都是整数 a b c and d是已知的 我如何找到整体解决方案x and y 如果我的想法是正确的 将会有无限多个解 由最小公倍数分隔b and d 但我只需要一个解决方案 我可以计算其余的 这是一个例
  • C# 列表通用扩展方法与非通用扩展方法

    这是一个简单的问题 我希望 集合类中有通用和非通用方法 例如List
  • 使用 C# 中的 CsvHelper 将不同文化的 csv 解析为十进制

    C 中 CsvHelper 解析小数的问题 我创建了一个从 byte 而不是文件获取 csv 文件的类 并且它工作正常 public static List
  • C 编程:带有数组的函数

    我正在尝试编写一个函数 该函数查找行为 4 列为 4 的二维数组中的最大值 其中二维数组填充有用户输入 我知道我的主要错误是函数中的数组 但我不确定它是什么 如果有人能够找到我出错的地方而不是编写新代码 我将不胜感激 除非我刚去南方 我的尝
  • 复制目录下所有文件

    如何将一个目录中的所有内容复制到另一个目录而不循环遍历每个文件 你不能 两者都不Directory http msdn microsoft com en us library system io directory aspx nor Dir
  • C++ 继承的内存布局

    如果我有两个类 一个类继承另一个类 并且子类仅包含函数 那么这两个类的内存布局是否相同 e g class Base int a b c class Derived public Base only functions 我读过编译器无法对数
  • 使用特定参数从 SQL 数据库填充组合框

    我在使用参数从 sql server 获取特定值时遇到问题 任何人都可以解释一下为什么它在 winfom 上工作但在 wpf 上不起作用以及我如何修复它 我的代码 private void UpdateItems COMBOBOX1 Ite
  • 当文件流没有新数据时如何防止fgets阻塞

    我有一个popen 执行的函数tail f sometextfile 只要文件流中有数据显然我就可以通过fgets 现在 如果没有新数据来自尾部 fgets 挂起 我试过ferror and feof 无济于事 我怎样才能确定fgets 当
  • C++ 中的参考文献

    我偶尔会在 StackOverflow 上看到代码 询问一些涉及函数的重载歧义 例如 void foo int param 我的问题是 为什么会出现这种情况 或者更确切地说 你什么时候会有 对参考的参考 这与普通的旧参考有何不同 我从未在现
  • DotNetZip:如何提取文件,但忽略zip文件中的路径?

    尝试将文件提取到给定文件夹 忽略 zip 文件中的路径 但似乎没有办法 考虑到其中实现的所有其他好东西 这似乎是一个相当基本的要求 我缺少什么 代码是 using Ionic Zip ZipFile zf Ionic Zip ZipFile
  • 类型或命名空间“MyNamespace”不存在等

    我有通常的类型或命名空间名称不存在错误 除了我引用了程序集 using 语句没有显示为不正确 并且我引用的类是公共的 事实上 我在不同的解决方案中引用并使用相同的程序集来执行相同的操作 并且效果很好 顺便说一句 这是VS2010 有人有什么
  • 从 mvc 控制器使用 Web api 控制器操作

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

随机推荐

  • 当找到预期结果时是否可以从 lambda 中中断

    我是Python新手 刚刚对Lambda表达式非常感兴趣 我遇到的问题是使用 lambda 过滤器从元素列表中找到一个且仅有一个目标元素 理论上 当找到目标元素时 就没有再继续下去的意义了 With for loop这很简单break循环
  • jQuery Jcrop setSelect 直观显示,但是点击移动时会跳转

    我正在使用 jQuery 插件 Jcrop 我对名为 setSelect 的初始设置之一有疑问 该属性接受一个包含两组 x 和 y 坐标 左上角和右下角 的数组 img src blah
  • 如何让输出显示在 Visual Studio 2005 错误列表的“消息”窗格中?

    我有一个像这样的头文件 ifndef GEN NOTE MARKERS TO DEVELOPERS HPP define GEN NOTE MARKERS TO DEVELOPERS HPP ifdef DEBUG macros for t
  • 如何在 DRF 中序列化通用外键

    我有带有通用外键的模型 我想序列化该模型 model py class AddressType models Model content type models ForeignKey ContentType object id models
  • 使用调试器 gdb 时未知的结束信号

    我已经在 Mac OS X 上安装了 GDB 为了测试它是否有效 我使用了以下 C 程序 include
  • 为所有实体设置默认分配大小?

    我想将默认设置为 50 的默认 AllocationSize 设置为另一个值 有没有办法做到这一点 我更喜欢使用默认的 JPA 来执行此操作 但 Eclipselink 也可以 我不想在我使用的每个实体中指定分配大小 TableGenera
  • 如何使用 AntiXss 库正确清理内容?

    我有一个简单的论坛应用程序 当有人发布任何内容时 我会 post Content Sanitizer GetSafeHtml post Content 现在 我不确定我是否做错了什么 或者发生了什么 但它不允许几乎没有 html 甚至简单
  • System.Data.SqlClient.SqlException:“关键字“Table”附近的语法不正确。”

    我正在尝试使用 Windows 窗体 C 创建一个登录系统 但它给了我一个错误 我正在使用 MySQL 数据库和来自 youtube 的教程 我不知道出了什么错误 该项目包含三个表单 登录表单 注册表单和主程序表单 using System
  • 设置带有条件的标题属性并使用角度翻译

    我在某些条件下使用标题属性 我的代码是 li title span pack details span li 当管理员为真时 它会显示购买许可证包 但是如何使用翻译过滤器将 1 变为 i18n 键 我试过这个 li title span p
  • 无法使用 Azure DevOps Pull 请求对构建错误进行排队

    我想在拉取请求开始合并之前触发构建 在 Azure DevOps 中 对于此选项 我在分支策略下添加了构建验证 但是 如果我创建了一个新的拉取请求 我会收到 无法对构建进行排队 的消息 请任何人告诉我我选择的选项解决了我的要求 如果是 如何
  • 使用node js从ftp站点下载多个文件

    我正在尝试从根文件夹下载 ftp 服务器上的每个文件 我所做的是这样的 ftpClient ls function err res res forEach function file console log file name ftpCli
  • matplotlib 刻度厚度

    有没有一种方法可以增加 matplotlib 中刻度的厚度和大小 而不必编写如下长段代码 for line in ax1 yaxis get ticklines line set markersize 25 line set markere
  • 如何将公式转换为析取范式?

    说给定一个公式 t1 gt 2 或 t2 gt 3 且 t3 gt 1 我希望得到它的析取范式 t1 gt 2 且 t3 gt 1 或 t2 gt 3 且 t3 gt 1 在Z3中如何实现这一点 Z3没有将公式转换为DNF的API或策略 然
  • 使用 python 访问 HDInsight Hive

    我们有一个 HDInsight 集群 其中包含 HIVE 中的一些表 我想从客户端计算机 Azure 外部 的 Python 3 6 查询这些表 我尝试过使用PyHive pyhs2并且impyla但我遇到了所有这些问题 有没有人有一个访问
  • C 在结构体中初始化数组

    我想要在结构中包含一个可变长度数组 但在正确初始化它时遇到问题 struct Grid int rows int cols int grid int main struct Grid testgrid 1 3 4 5 6 我尝试的所有操作都
  • Elasticsearch 6.2 中的精确匹配、不区分大小写的匹配,无需标准化

    我查看了我能找到的关于执行完全匹配 不区分大小写的查询的每一篇文章和帖子 但在实现后 它们并没有执行我正在寻找的内容 在将此问题标记为重复之前 请阅读整篇文章 给定一个用户名 我想查询我的 Elasticsearch 数据库以仅返回与用户名
  • 两个相关 for 循环的复杂度,外层循环的复杂度为 log n

    问题 计算该算法的复杂度 for i n i gt 1 i i 2 for j i j
  • Laravel 默认 auth 模块翻译

    我已经生成了默认的 Laravel auth 模块 在模块刀片的各处 我都看到双下划线 假设翻译即将完成的函数 例如 li a class nav link href Login a li 我的问题 翻译文件在哪里 如果我创建一个 我应该把
  • Django 表单下拉字段中的占位符

    我对 django 形式的下拉字段有一个小问题 我想添加到此字段占位符 或不作为占位符的第一个选项 和一些其他内容 如无标签 类等 我写了这样的东西 在我的forms py但现在我的表单已损坏 不要将值保存到数据库中 from models
  • noexcept 在派生类中的用法

    我在使用时遇到问题noexcept派生类上的说明符 更准确地说 当父类是抽象类时 具有protected构造函数 以下是我声明类的方式的示例 With a public基类中的构造函数 一切正常 与相同的代码protected并且派生类不再