在我看来,似乎是协议,当移动构造函数为noexcept(false)时,标准库必须调用复制构造函数而不是移动构造函数.
现在我不明白为什么会这样.此外,Visual Studio VC v140和gcc v 4.9.2似乎也有不同的做法.
我不明白为什么除了这是例如矢量的关注.我的意思是如果T没有,vector :: resize()应该如何能够提供强大的异常保证.正如我所看到的那样,矢量的异常级别将取决于T.无论是否使用复制或移动.我理解noexcept只是对编译器进行异常处理优化的眨眼.
当使用Visual Studio编译时,这个小程序在使用gcc编译时调用复制构造函数并移动构造函数.
include <iostream>
#include <vector>
struct foo {
foo() {}
// foo( const foo & ) noexcept { std::cout << "copy\n"; }
// foo( foo && ) noexcept { std::cout << "move\n"; }
foo( const foo & ) { std::cout << "copy\n"; }
foo( foo && ) { std::cout << "move\n"; }
~foo() noexcept {}
};
int main() {
std::vector< foo > v;
for ( int i = 0; …Run Code Online (Sandbox Code Playgroud) 无论我在互联网上阅读什么,强烈建议如果我希望我的班级能够很好地使用std::vector(即从我的班级移动语义std::vector),我应该将构造函数移动为"noexcept"(或noexcept(true)).
std::vector使用它,即使我将其标记noexcept(false)为实验?#include <iostream>
#include <vector>
using std::cout;
struct T
{
T() { cout <<"T()\n"; }
T(const T&) { cout <<"T(const T&)\n"; }
T& operator= (const T&)
{ cout <<"T& operator= (const T&)\n"; return *this; }
~T() { cout << "~T()\n"; }
T& operator=(T&&) noexcept(false)
{ cout <<"T& operator=(T&&)\n"; return *this; }
T(T&&) noexcept(false)
{ cout << "T(T&&)\n"; }
};
int main()
{
std::vector<T> t_vec;
t_vec.push_back(T());
}
Run Code Online (Sandbox Code Playgroud)
T()
T(T&&) …Run Code Online (Sandbox Code Playgroud) I am learning the behavior of std::vector: how it relocates (copies/moves) objects when reserving more capacity:
#include<vector>
#include<iostream>
using namespace std;
struct A{
A(const A& a){ i=a.i; cerr<<"copied "<<i<<endl; } //(1)
A( A&& a){ i=a.i; cerr<<"moved "<<i<<endl; }
A(int i):i(i){cerr<<"created "<<i<<endl;};
A(){};
private:
int i=0;
};
int main()
{
vector<A> v1;
size_t prevcap=v1.capacity();
for(int i=0; i<10; ++i){
v1.emplace_back(i);
if(prevcap!=v1.capacity()){
cerr<<"capacity increased to "<<v1.capacity()<<endl;
prevcap=v1.capacity();
}
cerr<<"------"<<endl;
}
}
Run Code Online (Sandbox Code Playgroud)
With my g++-10 the output is:
created 0
capacity increased to …Run Code Online (Sandbox Code Playgroud)