noexcept签名不影响copy/move的选择,这是VC的bug吗

C++语言 码拜 9年前 (2016-04-13) 863次浏览
[Effective modern C++]上面说,vector::push_back当capacity不够的时候,会申请一块新的内存,把原有的内容copy或move过去。
根据一个类的move构造函数能否是noexcept来判定,这样能够保证迁移到新的内存块的时候,有exception safety.
于是本人做了一个实验

#include<iostream>
#include<vector>
using namespace std;
struct A{
    A(){}
    A(const A&){ cout << "copy ctor\n"; }
    A(A&&){ cout << "move ctor\n"; }//能否noexcept,影响结果
};
int main()
{
    vector<A> vi(2);
    size_t c = 0;
    cout<<"========\n";
    for (size_t i = 0; i<4; ++i)
    {
        cout<<"push_back...........\n";
        vi.push_back(A());
        if (vi.capacity()>c)
        {
            c = vi.capacity();
            cout << c << endl;
        }
    }
    return 0;
}

GCC/clang运行这个程序,push_back假如capacity不够了,那么会把原有的元素copy一份。假如本人把move语义构造函数改成A(A&&)noexcept签名,那么调用的就是把原有的元素move一份。
这个和书上说的是一样的。
但是VC2013/2015本人做的测试,无论本人有没有加上noexcept,都是用move语义去搬移元素到新的内存块。这是VC实现的问题吗?
还是说,VC有特别的编译选项控制exception safe,默认是关闭的,打开了才是和GCC/clang一样的行为?
谢谢

解决方案

33

C++ 并不要求只在 move constructor 有 noexcept 时 move 。这是 libstdc++ 本人做的事情。

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明noexcept签名不影响copy/move的选择,这是VC的bug吗
喜欢 (0)
[1034331897@qq.com]
分享 (0)