假设我有两个向量,我将一个向另一个移动v1 = std::move(v2); v2在此之后还会处于可用状态吗?
我已经阅读了关于C++ 11中移动语义的一些描述,我想知道它可以在什么上下文中使用.目前,许多C++数学库使用模板元编程来延迟评估.
如果M = A + B + C*D,其中M,A,B,C和D是矩阵,则模板元编程允许避免无用的副本.移动语义是一种更方便的方式来做这些事吗?
如果不是,则在什么上下文中使用移动语义.如果是,与模板元编程相比,这种用途有什么区别/限制?
在这个问题中讨论了什么时候在C++ 11中创建一个不可移动的类型,我发现Scott Meyers在comp.std.c ++上有类似的问题,其中列出的类类型下面的SG在C++ 11中不可移动.
问题是为什么all iterators / iterator adaptors不能移动?
MSDN文章如何:编写移动构造函数具有以下建议.
如果为类提供移动构造函数和移动赋值运算符,则可以通过编写移动构造函数来调用移动赋值运算符来消除冗余代码.以下示例显示了调用移动赋值运算符的移动构造函数的修订版本:
// Move constructor.
MemoryBlock(MemoryBlock&& other)
: _data(NULL)
, _length(0)
{
*this = std::move(other);
}
Run Code Online (Sandbox Code Playgroud)
这个代码是通过双重初始化MemoryBlock的值来实现低效的,还是编译器能够优化掉额外的初始化?我是否应该通过调用移动赋值运算符来编写移动构造函数?
在RPC通信协议中,在调用方法之后,我将"完成"消息发送回调用者.由于以并发方式调用方法,因此包含响应(a std::string)的缓冲区需要由互斥锁保护.我想要实现的目标如下:
void connection::send_response()
{
// block until previous response is sent
std::unique_lock<std::mutex> locker(response_mutex_);
// prepare response
response_ = "foo";
// send response back to caller. move the unique_lock into the binder
// to keep the mutex locked until asio is done sending.
asio::async_write(stream_,
asio::const_buffers_1(response_.data(), response_.size()),
std::bind(&connection::response_sent, shared_from_this(),
_1, _2, std::move(locker))
);
}
void connection::response_sent(const boost::system::error_code& err, std::size_t len)
{
if (err) handle_error(err);
// the mutex is unlocked when the binder is destroyed
}
Run Code Online (Sandbox Code Playgroud)
但是,这无法编译,因为boost::asio需要处理程序是CopyConstructible. …
编译器一直在抱怨我试图将左值绑定到右值引用,但我看不出如何.我是C++ 11的新手,移动语义等,所以请耐心等待.
我有这个功能:
template <typename Key, typename Value, typename HashFunction, typename Equals>
Value& FastHash<Key, Value, HashFunction, Equals>::operator[](Key&& key)
{
// Some code here...
Insert(key, Value()); // Compiler error here
// More code here.
}
Run Code Online (Sandbox Code Playgroud)
它调用这个方法:
template <typename Key, typename Value, typename HashFunction, typename Equals>
void FastHash<Key, Value, HashFunction, Equals>::Insert(Key&& key, Value&& value)
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
我不断收到如下错误:
cannot convert argument 1 from 'std::string' to 'std::string &&'
Run Code Online (Sandbox Code Playgroud)
在Insert()调用上.是不是key在运算符重载中定义为右值?为什么它被重新解释为左值?
谢谢.
我有一些swap为某些类实现的C++ 03代码,以便std::sort快速生成(和其他函数).
不幸的是,std::sort现在似乎使用了std::move,这意味着我的代码现在比C++ 03 慢得多.
我知道我可以#if __cplusplus >= 201103L用来有条件地定义一个move-constructor/move-assignment操作符,但是我想知道是否有更好的方法不使用预处理器hacks?
(我想避免使用预处理程序,因为它们会很难看,因为我不仅需要测试编译器版本_MSC_VER >= 1600,还因为它们不适用于像LZZ这样不能识别C++的工具11移动语法,但强迫我预处理代码.)
这是类的移动构造函数X:
X::X(X&& rhs)
: base1(std::move(rhs))
, base2(std::move(rhs))
, mbr1(std::move(rhs.mbr1))
, mbr2(std::move(rhs.mbr2))
{ }
Run Code Online (Sandbox Code Playgroud)
这些是我警惕的事情:
rhs 两次,并rhs不能保证在一个有效的状态.是不是初始化的未定义行为base2?rhs到mbr1和mbr2,但由于rhs已经从移动(并再次,它不能保证是一个有效的状态)为什么要做这项工作?这不是我的代码.我在一个网站上找到了它.这个移动构造函数安全吗?如果是这样,怎么样?
考虑一下片段
struct Foo {
dummy: [u8; 65536],
}
fn bar(foo: Foo) {
println!("{:p}", &foo)
}
fn main() {
let o = Foo { dummy: [42u8; 65536] };
println!("{:p}", &o);
bar(o);
}
Run Code Online (Sandbox Code Playgroud)
该计划的典型结果是
0x7fffc1239890
0x7fffc1229890
Run Code Online (Sandbox Code Playgroud)
地址不同的地方.
显然,大型数组dummy已被复制,正如编译器的移动实现中所期望的那样.不幸的是,这可能会产生非平凡的性能影响,因为这dummy是一个非常大的阵列.这种影响可以迫使人们选择通过引用来传递参数,即使函数实际上在概念上"消耗"了参数.
由于Foo没有派生Copy,对象o被移动.由于Rust禁止访问被移动的对象,是什么阻止bar了"重用"原始对象o,迫使编译器生成一个可能昂贵的按位复制?是否存在根本性的困难,或者我们是否会看到编译器有一天会优化掉这个逐位复制?
以下肯定有效,但非常繁琐:
T(const T&) = delete;
T(T&&) = delete;
T& operator=(const T&) = delete;
T& operator=(T&&) = delete;
Run Code Online (Sandbox Code Playgroud)
我正试图发现最简洁的方式.以下工作会吗?
T& operator=(T) = delete;
Run Code Online (Sandbox Code Playgroud)
更新
请注意,我选择T& operator=(T)而不是T& operator=(const T&)或T& operator=(T&&),因为它可以同时满足两个目的.
move-semantics ×10
c++ ×9
c++11 ×9
boost ×1
boost-asio ×1
copy ×1
iterator ×1
llvm-codegen ×1
rust ×1
templates ×1
visual-c++ ×1