假设我有一个标记为的函数,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) 我正在使用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++ 初学者,正在学习一些 C++11 功能。我注意到的一件事是,在 Visual C++ stdlib 的某些部分中,作者使用了宏_NOEXCEPT而不是noexcept关键字。将鼠标悬停在宏上显示#define _NOEXCEPT noexcept,所以我有点困惑它的意义是什么。两者之间有什么区别,我应该选择其中一个而不是另一个?
编辑:我刚刚在 GitHub 上搜索了它,看起来clang也使用了它,所以它不是 Visual C++ 特定的宏。
是否允许标准书写decltype(::new (nullptr) T(std::declval< Args >()...))或noexcept(::new (nullptr) T(std::declval< Args >()...))?特别感兴趣的new是nullptr正确性.考虑以下代码:
#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 …
标准库定义了数组的交换,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,即,如果用于交换Widget是noexcept.
即,反过来,确定其他互换,如一个用于数组的数组是否Widget是noexcept.
类似地,交换std::pair包含Widgets的两个对象noexcept是否取决于Widgets的交换是否为noexcept.
但是根据这个解释,我无法理解为什么有必要将呼叫嵌套为noexcept(noexcept(swap(*a, *b))).
如果目标是"交换两个数组应该noexcept像交换元素一样",为什么还noexcept(swap(*a, *b))不够?
这些不同的重载是 …
这是一个两部分的问题,第一部分是关于完全用 C++ 编写的东西,第二部分是关于用 C 编写但从 C++ 调用的函数之间的交互。
让不同的翻译单元noexcept在同一函数的声明中看到不同的说明符是 ODR 还是其他违规行为?具体来说,如果一个单位看到:
void foo();
Run Code Online (Sandbox Code Playgroud)
而另一个人看到:
void foo() noexcept;
Run Code Online (Sandbox Code Playgroud)
这是 ODR 还是其他违规行为?您可能会假设该函数实际上永远不会抛出(即,它实际上可以被声明noexcept)。
如果所有 C++ 代码都将声明视为extern "C" void foo() noexcept;,但该函数实际上是在 C 中定义(实现)的,其中声明(显然)不包含noexcept?
基本上按照标准:
继承构造函数 (12.9) 和隐式声明的特殊成员函数(第 12 条)具有异常规范。如果
f是继承构造函数或隐式声明的默认构造函数、复制构造函数、移动构造函数、析构函数、复制赋值运算符或移动赋值运算符,则当且仅当异常规范允许时,其隐式异常规范指定类型 ID的隐式定义 直接调用的函数;如果它直接调用的任何函数允许所有异常,并且具有异常规范,则允许所有异常TTfffnoexcept(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++ 。特别是最近学习了使用《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
根据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?
未指定对ostream运算符<<的调用是否会失败或引发任何异常,而我从未遇到过。
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)