标签: noexcept

标记为noexcept的函数内部是否有例外?

假设我有一个标记为的函数,noexcept但里面有一行代码可以抛出.那行代码将在try块中,异常将被捕获.这会导致什么吗?

void MyFunc() noexcept
{
    try {
        throw std::exception("...");
    } catch (const std::exception & e) {
        // I'll deal with it here...
    }
}
Run Code Online (Sandbox Code Playgroud)

c++ exception noexcept c++11

3
推荐指数
2
解决办法
1176
查看次数

移动赋值运算符上的异常说明符如何影响移动构造函数?

我正在使用GCC 5.2和clang 3.6进行测试,两者都在C++ 14模式下,并且它们提供相同的输出.

对于以下代码

#include <iostream>
#include <type_traits>

struct S {
  // S& operator= (S&&) noexcept { return *this; }
};


int main() {
  std::cout << std::is_nothrow_move_constructible<S>::value
            << std::is_nothrow_move_assignable<S>::value;  
}
Run Code Online (Sandbox Code Playgroud)

11得到的结果.但是如果取消注释移动赋值运算符,则输出变为01.如何noexcept对移动赋值运算符的显式规范可能会影响移动构造函数的规范?

c++ exception language-lawyer noexcept c++14

3
推荐指数
2
解决办法
264
查看次数

noexcept 关键字和 _NOEXCEPT 宏有什么区别?

我是 C++ 初学者,正在学习一些 C++11 功能。我注意到的一件事是,在 Visual C++ stdlib 的某些部分中,作者使用了宏_NOEXCEPT而不是noexcept关键字。将鼠标悬停在宏上显示#define _NOEXCEPT noexcept,所以我有点困惑它的意义是什么。两者之间有什么区别,我应该选择其中一个而不是另一个?


编辑:我刚刚在 GitHub 上搜索了它,看起来clang也使用了它,所以它不是 Visual C++ 特定的宏。

c++ macros noexcept c++11

3
推荐指数
1
解决办法
1452
查看次数

在decltype()或operator noexcept()上下文中使用new new on nullptr

是否允许标准书写decltype(::new (nullptr) T(std::declval< Args >()...))noexcept(::new (nullptr) T(std::declval< Args >()...))?特别感兴趣的newnullptr正确性.考虑以下代码:

#include <type_traits>
#include <utility>

struct S { S(int) { ; } ~S() = delete; };

struct A
{
    template< typename T,
              bool is_noexcept = noexcept(::new (nullptr) S(std::declval< T >())) >
    A(T && x) noexcept(is_noexcept)
        : s(new S(std::forward< T >(x)))
    { ; }

    S * s;
};

static_assert(std::is_constructible< A, int >{});
static_assert(!std::is_constructible< A, void * >{});
Run Code Online (Sandbox Code Playgroud)

Disabler typename = decltype(S(std::declval< T >()))需要存在析构函数,但不需要放置new …

c++ decltype noexcept c++11 c++14

3
推荐指数
1
解决办法
328
查看次数

递归noexcept()的含义是什么?

标准库定义了数组的交换,std::pair如下所示:

template <class T, size_t N>
void swap(T (&a)[N],
          T (&b)[N]) noexcept(noexcept(swap(*a, *b)));

template <class T1, class T2>
struct pair {
    …
    void swap(pair& p) noexcept(noexcept(swap(first,  p.first)) &&
                                noexcept(swap(second, p.second)));
    …
};
Run Code Online (Sandbox Code Playgroud)

有效的现代C++第14项说:

[...]它们是否noexcept取决于noexcept条款中的表达方式noexcept.
给定两个阵列Widget,例如,交换它们是noexcept仅当在阵列中交换单独的元件是noexcept,即,如果用于交换Widgetnoexcept.
即,反过来,确定其他互换,如一个用于数组的数组是否Widgetnoexcept.
类似地,交换std::pair包含Widgets的两个对象noexcept是否取决于Widgets的交换是否为noexcept.

但是根据这个解释,我无法理解为什么有必要将呼叫嵌套为noexcept(noexcept(swap(*a, *b))).

如果目标是"交换两个数组应该noexcept像交换元素一样",为什么还noexcept(swap(*a, *b))不够?

这些不同的重载是 …

c++ noexcept

3
推荐指数
1
解决办法
61
查看次数

在声明中使用不一致的 noexcept 是否违反 ODR?

这是一个两部分的问题,第一部分是关于完全用 C++ 编写的东西,第二部分是关于用 C 编写但从 C++ 调用的函数之间的交互。

第1部分

让不同的翻译单元noexcept在同一函数的声明中看到不同的说明符是 ODR 还是其他违规行为?具体来说,如果一个单位看到:

void foo();
Run Code Online (Sandbox Code Playgroud)

而另一个人看到:

void foo() noexcept;
Run Code Online (Sandbox Code Playgroud)

这是 ODR 还是其他违规行为?您可能会假设该函数实际上永远不会抛出(即,它实际上可以被声明noexcept)。

第2部分

如果所有 C++ 代码都将声明视为extern "C" void foo() noexcept;,但该函数实际上是在 C 中定义(实现)的,其中声明(显然)不包含noexcept?

c c++ one-definition-rule language-lawyer noexcept

3
推荐指数
1
解决办法
120
查看次数

如果可能,隐式移动构造函数应为 noexcept

基本上按照标准:

继承构造函数 (12.9) 和隐式声明的特殊成员函数(第 12 条)具有异常规范。如果f是继承构造函数或隐式声明的默认构造函数、复制构造函数、移动构造函数、析构函数、复制赋值运算符或移动赋值运算符,则当且仅当异常规范允许时,其隐式异常规范指定类型 ID的隐式定义 直接调用的函数;如果它直接调用的任何函数允许所有异常,并且具有异常规范,则允许所有异常TTfff noexcept(true) 如果它直接调用的每个函数都不允许例外。

因此,截取的以下代码应具有隐式noexcept移动构造函数:

template<typename _Tp>
class Foo
{
public:
    Foo() = default;
    explicit Foo(const std::string& s, const std::function<bool(_Tp&)>& f) : stringField(s), funcField(f) {}

private:
    const std::string stringField;
    std::function<bool(_Tp&)> funcField;
};
Run Code Online (Sandbox Code Playgroud)

但不幸的是,它没有:

int main()
{
    std::cout << "std::string: " << std::is_nothrow_move_constructible_v<std::string> << std::endl;
    std::cout << "std::function: " << std::is_nothrow_move_constructible_v<std::function<bool(std::string&)>> << std::endl;
    std::cout …
Run Code Online (Sandbox Code Playgroud)

c++ move-constructor noexcept

3
推荐指数
1
解决办法
54
查看次数

使用 noexcept 的程序被 msvc 和 clang 接受但被 gcc 拒绝

我正在使用此处列出的书籍学习 C++ 。特别是最近学习了使用《C++ Primer》noexcept这本书。现在,为了进一步明确我对这个主题的概念并确认我已经正确理解了事情,我正在编写简单的程序。下面给出了一个这样的程序,它可以使用 MSVC 和 Clang 编译,但不能使用 GCC 编译。演示

void f() noexcept(5) //accepted by msvc but rejected by gcc
{

}
Run Code Online (Sandbox Code Playgroud)

所以我的问题是哪个编译器就在这里(如果有的话)?

以下是一些主要编译器的结果:

编译器 C++版本 接受代码
海湾合作委员会 C++17
海湾合作委员会 C++20
C++17 是的
C++20
MSVC C++17 是的
MSVC C++20 是的

正如我们所看到的,该程序适用于某些编译器,但不适用于其他编译器。gcc 中的错误说: error: narrowing conversion of '5' from 'int' to 'bool'

c++ exception-specification language-lawyer narrowing noexcept

3
推荐指数
1
解决办法
117
查看次数

std::span 构造函数是否缺少 noexcept?

根据cppreference的构造函数(2)std::span定义为

template< class It >
explicit(extent != std::dynamic_extent)
constexpr span( It first, size_type count );
Run Code Online (Sandbox Code Playgroud)

例外情况列为2) Throws nothing.

如果这个构造函数“什么都不抛出”,那么为什么它甚至被列在异常下,为什么构造函数没有标记为 noexcept?

c++ stl exception noexcept

3
推荐指数
1
解决办法
136
查看次数

iostream运算符重载的C ++异常规范

未指定对ostream运算符<<的调用是否会失败或引发任何异常,而我从未遇到过。

  1. 是否存在ostream operator <<可能失败的情况?
  2. 如果否,为什么标准不对这些重载不加任何其他说明?
  3. 以下重载有效吗?好的做法?常用的?
  4. istream运算符有相同问题>>
struct MyClass {
    int data;
    // I/O operators with noexcept specifier
    friend std::istream& operator>>(std::istream &in, MyClass &obj) noexcept;
    friend std::ostream& operator<<(std::ostream &out, const MyClass &obj) noexcept;
};
Run Code Online (Sandbox Code Playgroud)

c++ iostream operator-overloading noexcept

2
推荐指数
1
解决办法
37
查看次数