相关疑难解决方法(0)

C++ 11中删除函数的确切语义是什么?

struct A
{
    A();

    A(const A&);
    A& operator =(const A&);

    A(A&&) = delete;
    A& operator =(A&&) = delete;
};

struct B
{
    B();

    B(const B&);
    B& operator =(const B&);    
};

int main()
{
    A a;
    a = A(); // error C2280

    B b;
    b = B(); // OK
}
Run Code Online (Sandbox Code Playgroud)

我的编译器是VC++ 2013 RC.

错误C2280:'A&A :: operator =(A &&)':尝试引用已删除的函数

我只是想知道为什么编译器A& operator =(const A&);A& operator =(A&&)删除时不会尝试?

这种行为是由C++标准定义的吗?

c++ overloading language-lawyer c++11 semantics

45
推荐指数
2
解决办法
5310
查看次数

具有抑制移动构造/分配的类型如何仍被认为是可移动的?

struct copyable { // and movable
  copyable() = default;
  copyable(copyable const&) { /*...*/ };
  copyable& operator=(copyable const&) { /*...*/ return *this; }
};
Run Code Online (Sandbox Code Playgroud)

由于复制构造函数和复制赋值操作函数是显式定义的,因此它表示编译器不能隐式定义移动构造函数和移动赋值函数,因此不允许移动操作.

能告诉我上述理解是否正确吗?

c++ move-semantics c++11

26
推荐指数
1
解决办法
1630
查看次数

何时调用Move Constructor?

我很困惑何时调用移动构造函数与复制构造函数.我已经阅读了以下资料:

移动构造函数未在C++ 0x中调用

在C++ 11中移动语义和右值引用

MSDN

所有这些来源要么过于复杂(我只想要一个简单的例子),要么只展示如何编写移动构造函数,而不是如何调用它.我写了一个简单的问题更具体:

const class noConstruct{}NoConstruct;
class a
{
private:
    int *Array;
public:
    a();
    a(noConstruct);
    a(const a&);
    a& operator=(const a&);
    a(a&&);
    a& operator=(a&&);
    ~a();
};

a::a()
{
    Array=new int[5]{1,2,3,4,5};
}
a::a(noConstruct Parameter)
{
    Array=nullptr;
}
a::a(const a& Old): Array(Old.Array)
{

}
a& a::operator=(const a&Old)
{
    delete[] Array;
    Array=new int[5];
    for (int i=0;i!=5;i++)
    {
        Array[i]=Old.Array[i];
    }
    return *this;
}
a::a(a&&Old)
{
    Array=Old.Array;
    Old.Array=nullptr;
}
a& a::operator=(a&&Old)
{
    Array=Old.Array;
    Old.Array=nullptr;
    return *this;
}
a::~a()
{
    delete[] Array;
} …
Run Code Online (Sandbox Code Playgroud)

c++ move-constructor c++11

23
推荐指数
2
解决办法
2万
查看次数

MSVC 无法返回可以复制但不能移动的对象

在摆弄复制省略时,我遇到了这种奇怪的行为:

class Obj {
 public:
  Obj() = default;

  Obj(Obj&&) = delete;
  Obj(const Obj&) { std::cout << "Copy" << std::endl; }
};

Obj f1() {
  Obj o;
  return o; // error C2280: move constructor is deleted
}

Obj f2() {
  Obj o;
  return Obj(o); // this however works fine
}

int main() {
  Obj p = f1();
  Obj q = f2();

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

GCC 和 Clang 接受此代码并且能够在两种情况下使用复制省略。

f1()MSVC 中抱怨它无法返回,o因为Obj删除了 的移动构造函数。但是,我希望它能够依靠复制构造函数。这是 MSVC 中的错误还是这种期望的行为(我不明白)和 GCC/Clang …

c++ visual-c++ language-lawyer copy-elision c++17

23
推荐指数
2
解决办法
904
查看次数

最简洁的方法来禁用复制和移动语义

以下肯定有效,但非常繁琐:

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&&),因为它可以同时满足两个目的.

c++ copy move-semantics c++11

17
推荐指数
3
解决办法
2944
查看次数

为什么我要删除移动构造函数并在单例中移动赋值运算符?

我有以下Singleton策略类实现:

template <typename T>
class Singleton
{
    Singleton(){}; // so we cannot accidentally delete it via pointers
    Singleton(const Singleton&) = delete; // no copies
    Singleton& operator=(const Singleton&) = delete; // no self-assignments
    Singleton(Singleton&&) = delete; // WHY?
    Singleton& operator=(Singleton&&) = delete; // WHY?
public:
    static T& getInstance() // singleton
    {
        static T instance; // Guaranteed to be destroyed.
                       // Instantiated on first use.
                       // Thread safe in C++11
        return instance;
    }
};
Run Code Online (Sandbox Code Playgroud)

然后我通过奇怪的重复模板模式(CRTP)使用

class Foo: public Singleton<Foo> // now Foo …
Run Code Online (Sandbox Code Playgroud)

c++ singleton move-semantics c++11

16
推荐指数
1
解决办法
1万
查看次数

为什么删除的移动语义会导致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
查看次数