外部资源(如std::vector<T>或std::string)的"值类型"问题是复制它们往往非常昂贵,并且副本是在各种上下文中隐式创建的,因此这往往是性能问题.C++ 0x对这个问题的回答是移动语义,它在概念上基于资源窃取的思想,并且由rvalue引用技术驱动.
D是否有类似于移动语义或右值引用的东西?
可能重复:
如何在向量增长时强制执行移动语义?
insert,push_back和emplace(_back)可能导致的重新分配std::vector.我很困惑地看到以下代码复制元素而不是在重新分配容器时移动它们.
#include <iostream>
#include <vector>
struct foo {
int value;
explicit foo(int value) : value(value) {
std::cout << "foo(" << value << ")\n";
}
foo(foo const& other) noexcept : value(other.value) {
std::cout << "foo(foo(" << value << "))\n";
}
foo(foo&& other) noexcept : value(std::move(other.value)) {
other.value = -1;
std::cout << "foo(move(foo(" << value << "))\n";
}
~foo() {
if (value != -1)
std::cout << "~foo(" …Run Code Online (Sandbox Code Playgroud) 我有一个带有原子成员变量的类:
struct Foo
{
std::atomic<bool> bar;
/* ... lots of other stuff, not relevant here ... */
Foo()
: bar( false )
{}
/* Trivial implementation fails in gcc 4.7 with:
* error: use of deleted function ‘std::atomic<bool>::atomic(const td::atomic<bool>&)’
*/
Foo( Foo&& other )
: bar( other.bar )
{}
};
Foo f;
Foo f2(std::move(f)); // use the move
Run Code Online (Sandbox Code Playgroud)
移动构造函数应该怎么样?
GCC 4.7不喜欢我的任何企图(如添加std::move()周围other.bar)和净是出奇的安静这里...
何时隐式移动构造函数不够好?
我应该把它当作析构函数和复制构造函数来对待它,通常只有在我管理自己的内存时才需要吗?
在这个(非常人为的)场景中隐式移动构造函数是否足够好:
class A
{
private:
B b;
std::string name;
public:
A();
std::string getName() const {
return name;
}
B getB() const {
return b;
}
};
class B
{
private:
std::vector list;
public:
B();
std::vector getList() const {
return list;
}
};
Run Code Online (Sandbox Code Playgroud) 是否可以通过使用移动语义将临时std :: map的内容插入temp到另一个std :: map中m,以便临时值不被复制并重用?
让我们说有一个:
std::map<int, Data> temp;
std::map<int, Data> m;
Run Code Online (Sandbox Code Playgroud)
从复制值的一种方法temp为m是:
m.insert(temp.begin(),temp.end());
Run Code Online (Sandbox Code Playgroud)
我怎样才能移动的temp元素融入m,而不是复制?
我有一个定义如下的函数:
void foo(std::shared_ptr<X> x) { ... };
Run Code Online (Sandbox Code Playgroud)
如果我将共享ptr声明为X:
std::shared_ptr<X> sourcePtr(new X(...));
Run Code Online (Sandbox Code Playgroud)
然后我可以打电话foo如下:
foo(std::move(sourcePtr));
Run Code Online (Sandbox Code Playgroud)
要么
foo(sourcePtr);
Run Code Online (Sandbox Code Playgroud)
我明白,如果我使用第一个选项,则sourcePtr变为null.它是否也会阻止引用计数递增?
如果这无关紧要,我更喜欢哪个选项?做出这样的决定时,我应该考虑其他事情吗?
如果我构造一个由空格分隔的浮点值列表组成的字符串,使用std::ostringstream:
std::ostringstream ss;
unsigned int s = floatData.size();
for(unsigned int i=0;i<s;i++)
{
ss << floatData[i] << " ";
}
Run Code Online (Sandbox Code Playgroud)
然后我得到一个结果std::string:
std::string textValues(ss.str());
Run Code Online (Sandbox Code Playgroud)
但是,这将导致不必要的字符串内容的深层副本,因为ss将不再使用.
有没有办法在不复制整个内容的情况下构造字符串?
在即将推出的C++ 0x标准中,当在移动构造函数中/期间抛出异常时会发生什么?
原始物体会保留吗?或者是处于未定义状态的原始对象和移动对象?语言提供的保证是什么?
我一直在探索C++ 中Move Constructors的可能性,我想知道在下面的例子中有哪些方法可以利用这个功能.考虑以下代码:
template<unsigned int N>
class Foo {
public:
Foo() {
for (int i = 0; i < N; ++i) _nums[i] = 0;
}
Foo(const Foo<N>& other) {
for (int i = 0; i < N; ++i) _nums[i] = other._nums[i];
}
Foo(Foo<N>&& other) {
// ??? How can we take advantage of move constructors here?
}
// ... other methods and members
virtual ~Foo() { /* no action required */ }
private:
int _nums[N];
};
Foo<5> bar() …Run Code Online (Sandbox Code Playgroud)
考虑以下类,实现移动构造函数的正确方法是什么:
class C {
public:
C();
C(C&& c);
private:
std::string string;
}
Run Code Online (Sandbox Code Playgroud)
当然,这个想法是避免复制string或解除分配两次.
让我们假设基本的例子只是为了清晰,我确实需要一个移动构造函数.
我试过了:
C::C(C&& c) {
//move ctor
string = std::move(c.string);
}
Run Code Online (Sandbox Code Playgroud)
和
C::C(C&& c) : string(std::move(c.string)) {
//move ctor
}
Run Code Online (Sandbox Code Playgroud)
两者都在gcc 4.8上编译正常并运行良好.这似乎选项A是正确的行为,string被复制,而不是使用选项B.移动
这是正确执行的举动构造的?
c++ ×10
c++11 ×10
move-semantics ×10
atomic ×1
d ×1
exception ×1
libstdc++ ×1
shared-ptr ×1
stdvector ×1