相关疑难解决方法(0)

为什么删除的移动语义会导致std :: vector出现问题?

在做了一些研究之后,我发现C++ 11的分配器存在缺陷,需要类型可移动/可复制.我确定这是导致这个问题的原因,但我对删除和未声明的移动语义之间的行为感到困惑.

我有以下代码无法在MSVC12和Clang上编译:

#include <vector>

class Copyable
{
public:
   Copyable() = default;

   Copyable(Copyable const& other)
      : m_int(other.m_int)
   {}

   Copyable& operator= (Copyable const& other)
   {
      m_int = other.m_int;
      return *this;
   }

   Copyable(Copyable&&) = delete;
   Copyable& operator= (Copyable&&) = delete;

private:
   int m_int = 100;
};

int main()
{
   std::vector<Copyable> objects;
   objects.push_back(Copyable{});
}
Run Code Online (Sandbox Code Playgroud)

这无法在MSVC上编译:

xmemory0(600):错误C2280:'可复制::可复制(可复制&&)':尝试引用已删除的函数

而对于Clang(现场样本):

new_allocator.h:120:23:错误:调用'Copyable'的已删除构造函数

在这两种情况下,当我删除显式删除的移动构造/分配方法时,代码编译.AFAIK在声明复制赋值/构造方法时,编译器不会隐式声明相应的移动成员.所以它们仍应被有效删除,对吧?当我删除move construct/assign的显式删除时,为什么代码会编译?

一般来说,这个C++ 11缺陷有什么好的解决方法?我不希望我的物体可以移动(但它们是可复制的).

c++ c++11

10
推荐指数
2
解决办法
1095
查看次数

如果C++函数的返回类型是T,那么返回类型T的局部变量是否有效地使变量成为rvalue?

当我用GCC编译时:

struct A
  {
    A();
    A(const A &);
    A(A &&) = delete;
  };

void ugh(A);

A bar()
  {
    A a;
    ugh(a);
    return(a);
  }
Run Code Online (Sandbox Code Playgroud)

我收到错误:

x.cpp: In function ‘A bar()’:
x.cpp:14:13: error: use of deleted function ‘A::A(A&&)’
     return(a);
             ^
x.cpp:5:5: note: declared here
     A(A &&) = delete;
     ^
Run Code Online (Sandbox Code Playgroud)

实际上,将return语句中的a视为rvalue(因为它即将被销毁)确实是有意义的.但是,标准是否要求rvalues是匿名的?

此外,即使在这种情况下允许使用移动构造函数,为什么还需要它?为什么编译器不能使用复制构造函数,因为移动构造函数不可用?

他之前的问题的答案,返回本地对象是否需要移动语义?,主要解决我的问题,但不要触及命名变量如何成为没有调用std :: move()的右值.

编辑:这两个链接解释了为什么gcc的行为是正确的,并阐明了为什么标准需要这种行为: 为什么C++ 11删除的函数参与重载解析? http://en.cppreference.com/w/cpp/language/return

c++ c++11

5
推荐指数
0
解决办法
73
查看次数

标签 统计

c++ ×2

c++11 ×2