隐式生成的成员和noexcept [英] Implicit generated members and noexcept

查看:151
本文介绍了隐式生成的成员和noexcept的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近开始添加新的 noexcept 规范,尽可能移动构造函数/赋值。现在我开始想知道隐式生成的成员函数的异常规范是什么样子。由于 noexcept 移动函数允许使用更高效的代码路径(例如,当调整向量时)那些被声明为noexcept。我有问题,了解什么标准有关这一点,因此尝试下面的代码在g ++ 4.6(与 -std = c ++ 0x ),以获得一些抓地力上:

I recently started to add the new noexcept specification to move constructors/assignments wherever possible. Now I started to wonder what the exception specification of implicit generated member functions looks like. Since having noexcept move functions allows the use of more efficient code paths(e.g. when resizing a vector) I would hope that those are declared as noexcept whenever possible. I had problems understanding what the standard has to say about that and therefore tried the following code in g++4.6 (with -std=c++0x) to get some grip on it:

struct foobar{};
int main()
{
    foobar a, b;
    std::cout<<std::boolalpha
             <<noexcept(foobar())<<", "<<noexcept(foobar(a))<<", "
             <<noexcept(a = b)   <<", "<<noexcept(a = std::move(b))<<", "
             <<noexcept(foobar(std::move(a)))<<std::endl;
}

这给了我一个输出 True,True, True,False,False ,意味着默认和复制构造函数/赋值 noexcept ,而不移动操作。

This gave me an output of True, True, True, False, False, meaning that default and copy constructor/assignment where noexcept, while move operation where not.

现在我的问题:

在什么情况下是隐式生成宣告为 noexcept ?此外, foobar 正确或仅仅是gcc4.6中的编译器错误的后续行为

Under what circumstances are implicit generated (or defaulted) member functions declared as noexcept? Furthermore is the obseved behaviour for foobar correct or simply a compiler bug in gcc4.6?

推荐答案

库错误 - 它在gcc 4.7中显示 true,true,true,true,true

Library bug — it shows true, true, true, true, true in gcc 4.7.

并且该错误是不是生成的移动构造函数不是noexcept,但 std :: move 没有标记as noexcept ,我们可以看到额外的测试:

And the bug is not that the generated move constructors aren't noexcept, but that std::move is not marked as noexcept, as we can see with the additional tests:

std::cout << noexcept(a = static_cast<foobar&&>(b)) << ", "  // true
          << noexcept(foobar(static_cast<foobar&&>(b))) << ", " // true
          << noexcept(std::move(b)) << std::endl;   // false

gcc 4.6中的大多数库函数都不是noexcept-正确的,在 gcc 4.7 中解决,

Most of the library functions in gcc 4.6 was not noexcept-correct, and this has been addressed in gcc 4.7,

对于无限生成的成员函数为noexcept,这在§15.4/ 14中有记载。基本上, noexcept 如果所有需要调用的函数都是 noexcept

As for when the implcitely generated member functions are noexcept, this is documented in §15.4/14. Basically, it is noexcept if all functions it will need to call are all noexcept.


隐式声明的特殊成员函数(第12条)应具有异常规范。如果 f
隐式声明的默认构造函数,复制构造函数,移动构造函数,析构函数,复制赋值
运算符, em> exception-specification 指定 type-id T if and only
if T由 f 的隐式定义直接调用的函数的 exception-specification 允许 f
允许所有异常,如果它直接调用的任何函数允许所有异常 f 将允许没有异常
如果每个函数直接调用允许没有异常。

An implicitly declared special member function (Clause 12) shall have an exception-specification. If f is an implicitly declared default constructor, copy constructor, move constructor, destructor, copy assignment operator, or move assignment operator, its implicit exception-specification specifies the type-id T if and only if T is allowed by the exception-specification of a function directly invoked by f’s implicit definition; f shall allow all exceptions if any function it directly invokes allows all exceptions, and f shall allow no exceptions if every function it directly invokes allows no exceptions.

这篇关于隐式生成的成员和noexcept的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆