【问题标题】:move assignment not called for vector element向量元素不需要移动赋值
【发布时间】:2015-02-06 20:00:44
【问题描述】:

我是 c++11 的新手,我正在尝试尝试移动语义和右值函数参数。 我不明白为什么以下代码无法编译:

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;

【问题讨论】:

  • @MooingDuck 不,问题只是命名的右值引用,如e,是左值。
  • @T.C.:你绝对是对的。我有一半的把握我仍然是对的。
  • 什么 T.C.说...你需要v[index] = std::move(e);。但即便如此,add_entry 也毫无意义,因为您正在对 vector 的本地副本进行操作。
  • 而且字符串副本不正确,后面的'\0'被遗漏了

标签: c++ c++11


【解决方案1】:

在直接讨论编译错误之前,一定要把v在这个函数中引用。

void add_entry(vector<MatchEntry> &v, MatchEntry&& e, int index) {
                         //       |
                         //       `--- by reference here
  v.at(index) = std::move(e);
}

无论如何,问题在于e 是一个左值,因此该分配试图使用复制分配而不是移动分配。命名变量始终是左值,无论其类型是 MatchEntryMatchEntry&amp; 还是 MatchEntry&amp;&amp;。当然,我们知道e引用的对象是一个右值,因此我们可以用move告诉编译器把e当作一个右值。

(无关:但我总是喜欢使用.at(index) 访问向量。由于边界检查,它更安全。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-01
    • 2012-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-04
    • 1970-01-01
    相关资源
    最近更新 更多