隐式生成的成员和noexcept

Gri*_*zly 19 c++ language-lawyer c++11

我最近开始添加新noexcept规范以尽可能地移动构造函数/赋值.现在我开始想知道隐式生成的成员函数的异常规范是什么样的.由于具有noexcept移动函数允许使用更有效的代码路径(例如,在调整大小时vector),我希望尽可能将它们声明为noexcept.我在理解标准对此有何看法时遇到了问题,因此尝试使用g ++ 4.6(with -std=c++0x)中的以下代码来获取它:

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;
}
Run Code Online (Sandbox Code Playgroud)

这给了我一个输出True, True, True, False, False,意思是默认和复制构造函数/赋值所在noexcept,而移动操作不在哪里.

现在我的问题:

在什么情况下隐式生成(或默认)成员函数声明为noexceptfoobar在gcc4.6中,对于正确或简单的编译器错误,是否存在过时的行为?

ken*_*ytm 18

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

并且错误不是生成的移动构造函数不是noexcept,而是std::move没有标记为noexcept,正如我们可以看到的其他测试:

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

gcc 4.6中的大多数库函数都不是noexcept-correct,这已在gcc 4.7中解决,


至于无限制生成的成员函数是什么时候,这在第15.4/14节中有记载.基本上,noexcept如果它需要调用的所有函数都是noexcept.

隐式声明的特殊成员函数(第12条)应具有异常规范.如果f是隐式声明的默认构造函数,复制构造函数,移动构造函数,析构函数,复制赋值运算符或移动赋值运算符,则其隐式异常规范指定type-id T当且仅当函数T异常规范允许时才由f隐式定义调用; f如果它直接调用的任何函数允许所有异常,则允许所有异常,并且f如果它直接调用的每个函数都不允许异常,则不允许异常.

  • @Grizzly:我认为这意味着如果他们只调用`noexcept`函数它们将是`noexcept`(即实际函数是否与throw无关,异常规范是重要的) (6认同)