C++ 向量重新分配使用复制而不是移动构造函数
嗨,我使用GCC4.7创建了一个带有noexcept move构造函数的类Foo,并将向量保留大小设置为2,以便在添加第3项时必须重新分配大小。执行此操作时,似乎是在调用复制构造函数而不是移动构造函数。我是不是遗漏了什么C++ 向量重新分配使用复制而不是移动构造函数,c++,c++11,gcc,move-semantics,C++,C++11,Gcc,Move Semantics,嗨,我使用GCC4.7创建了一个带有noexcept move构造函数的类Foo,并将向量保留大小设置为2,以便在添加第3项时必须重新分配大小。执行此操作时,似乎是在调用复制构造函数而不是移动构造函数。我是不是遗漏了什么 #include <vector> #include <iostream> class Foo { public: Foo(int x) : data_(x) { std::cout << " constructing
#include <vector>
#include <iostream>
class Foo
{
public:
Foo(int x) : data_(x)
{
std::cout << " constructing " << std::endl;
}
~Foo()
{
std::cout << " destructing " << std::endl;
}
Foo& operator=(const Foo&) = default;
Foo& operator=(Foo&&) = default;
Foo(Foo&& other) noexcept : data_(std::move(other.data_))
{
std::cout << " Move constructing " << std::endl;
}
Foo(const Foo& other) noexcept : data_(other.data_)
{
std::cout << " Copy constructing " << std::endl;
}
private:
int data_;
};
int main ( int argc, char *argv[])
{
std::vector<Foo> v;
v.reserve(2);
v.emplace_back(1);
std::cout << "Added 1" << std::endl;
v.emplace_back(2);
std::cout << "Added 2" << std::endl;
v.emplace_back(3);
std::cout << "Added 3" << std::endl;
std::cout << "v size: " << v.size() << std::endl;
}
在使用GCC4.7和4.8对其进行了一些修补之后,似乎它确实是4.7中的一个bug,它只在类的析构函数未标记为noexcept时出现:
struct Foo {
Foo() {}
~Foo() noexcept {}
Foo(Foo&&) noexcept { std::cout << "move constructor" << std::endl; }
Foo(const Foo&) noexcept { std::cout << "copy constructor" << std::endl; }
};
int main() {
std::vector<Foo> v;
v.reserve(2);
v.emplace_back();
v.emplace_back();
v.emplace_back();
}
如果我们从析构函数中删除noexcept
:
struct Foo {
Foo() {}
~Foo() {}
Foo(Foo&&) noexcept { std::cout << "move constructor" << std::endl; }
Foo(const Foo&) noexcept { std::cout << "copy constructor" << std::endl; }
};
GCC 4.8在这两种情况下都使用移动构造函数。My clang build不会触发复制构造函数一次。获取更智能的gcc?它在gcc 4.8.1中按预期工作(即,
vector
调用移动构造函数)。它在gcc 4.8.1中工作正常。可能是4.7hmmm中的一个bug,这很有意义,我需要升级到GCC4.8.1。我永远都搞不懂这件事它一直困扰着我。。。那看起来只是个虫子。非常感谢+1 . G++4.7不应用析构函数为noexcept的规则,因此需要在析构函数上添加显式noexcept规范。GCC 4.8按照C++11的要求正确地使析构函数不例外。
move constructor
move constructor
struct Foo {
Foo() {}
~Foo() {}
Foo(Foo&&) noexcept { std::cout << "move constructor" << std::endl; }
Foo(const Foo&) noexcept { std::cout << "copy constructor" << std::endl; }
};
copy constructor
copy constructor