我是c ++ 11的新手,我正在尝试移动语义和rvalue函数参数。 我不明白为什么以下代码无法编译:
class MatchEntry
{
unique_ptr<char []> key;
public:
MatchEntry() {}
MatchEntry(const char *key_bytes, int key_nbytes) {
char *data = new char[key_nbytes];
copy(key_bytes, key_bytes + key_nbytes, data);
key = unique_ptr<char []>(data);
}
};
void add_entry(vector<MatchEntry> v, MatchEntry&& e, int index) {
v[index] = e;
}
class MatchEntry
具有unique_ptr
成员,因此编译器不能生成隐式复制赋值运算符。但是会生成移动赋值运算符。 add_entry
函数采用对MatchEntry
的右值引用,因此我希望调用移动赋值。但是当我尝试编译时出现以下错误:
gg.cpp: In function ‘void add_entry(std::vector<MatchEntry>, MatchEntry&&, int)’:
gg.cpp:57:12: error: use of deleted function ‘MatchEntry& MatchEntry::operator=(const MatchEntry&)’
v[index] = e;
^
gg.cpp:32:7: note: ‘MatchEntry& MatchEntry::operator=(const MatchEntry&)’ is implicitly deleted because the default definition would be ill-formed:
class MatchEntry
^
gg.cpp:32:7: error: use of deleted function ‘std::unique_ptr<_Tp [], _Dp>& std::unique_ptr<_Tp [], _Dp>::operator=(const std::unique_ptr<_Tp [], _Dp>&) [with _Tp = char; _Dp = std::default_delete<char []>]’
In file included from /usr/include/c++/4.9/memory:81:0,
from gg.cpp:1:
/usr/include/c++/4.9/bits/unique_ptr.h:599:19: note: declared here
unique_ptr& operator=(const unique_ptr&) = delete;
答案 0 :(得分:2)
在直接讨论编译错误之前,你绝对应该在这个函数中引用v
。
void add_entry(vector<MatchEntry> &v, MatchEntry&& e, int index) {
// |
// `--- by reference here
v.at(index) = std::move(e);
}
无论如何,问题是e
是左值,因此赋值是尝试使用复制赋值而不是移动赋值。命名变量始终是左值,无论其类型是MatchEntry
还是MatchEntry&
还是MatchEntry&&
。当然,我们知道e
引用的对象是一个右值,因此我们可以使用move
告诉编译器将e
视为右值。
(不相关:但我总是喜欢使用.at(index)
访问向量。由于边界检查,它更安全。)