- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我最近开始添加新的 noexcept
规范以尽可能移动构造函数/赋值。现在我开始想知道隐式生成的成员函数的异常规范是什么样的。由于具有 noexcept
移动函数允许使用更有效的代码路径(例如,在调整 vector
的大小时)我希望尽可能将它们声明为 noexcept。我无法理解标准对此的规定,因此尝试了 g++4.6 中的以下代码(使用 -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;
}
这给了我 True, True, True, False, False
的输出,这意味着 noexcept
的默认和复制构造函数/赋值,而没有的移动操作。
现在回答我的问题:
在什么情况下隐式生成(或默认)的成员函数声明为noexcept
?此外,观察到的 foobar
行为是正确的还是只是 gcc4.6 中的编译器错误?
最佳答案
库错误 - 它在 gcc 4.7 中显示 true, true, true, true, true
。
错误是 not 生成的移动构造函数不是 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
gcc 4.6 中的大多数库函数都不是 noexcept 正确的,这已在 gcc 4.7 中得到解决。 ,
至于隐含生成的成员函数何时为 noexcept,这在 §15.4/14 中有记录。基本上,如果它需要调用的所有函数都是 noexcept
,则它是 noexcept
。
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-idT
if and only ifT
is allowed by the exception-specification of a function directly invoked byf
’s implicit definition;f
shall allow all exceptions if any function it directly invokes allows all exceptions, andf
shall allow no exceptions if every function it directly invokes allows no exceptions.
关于c++ - 隐式生成的成员和 noexcept,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9180164/
我是一名优秀的程序员,十分优秀!