gcc意外调用已删除的移动构造函数

时间:2015-04-02 11:02:09

标签: c++11 gcc

我正在尝试编写一个非常简单的数组类,其函数返回自身的子部分。展示它比解释更容易......

template<typename T>
class myArrayType
{
   // Constructor; the buffer pointed to by 'data' must be held 
   // elsewhere and remain valid for the lifetime of the object
   myArrayType(int size, T* data) : n(size), p(data)
   {
   }

   // A move constructor and assign operator wouldn't make 
   //much sense for this type of object:
#ifndef _MSC_VER
    myArrayType(myArrayType<T> &&source) = delete;
    myArrayType & operator=(myArrayType<T> &&source) && = delete;
#else
  #if _MSC_VER >= 2000
      myArrayType(myArrayType<T> &&source) = delete;
      myArrayType & operator=(myArrayType<T> &&source) && = delete;
  #endif
  // Earlier versions of Visual C++ do not generate default move members
#endif

   // Various whole-array operations, which is the main reason for wanting to do this:
   myArrayType & operator+=(const myArrayType &anotherArray) & noexcept
   {
       for (int i=0; i<n; ++i) p[i] += anotherArray.p[i];
       return *this;
   }

   // etc.


   // The interesting bit: create a new myArrayType object which is 
   // a subsection of this one and shares the same memory buffer
   myArrayType operator()(int firstelement, int lastelement) noexcept
   {
       myArrayType newObject;
       newObject.p = &p[firstelement];
       newObject.n = lastelement - firstelement + 1;
       return newObject;
   }


private:
    T*  p;
    int n;
}

我当然想做的是能够写下:

double aBigBlobOfMemory[1000];  // Keep it on the stack
myArrayType<double> myArray(1000, aBigBlobOfMemory);

myArrayType<double> mySmallerArray = myArray(250, 750);

...所以'mySmallerArray'是一个完整形成的myArrayType对象,它包含指向myArray内存子集的指针。

在Visual Studio 2013中,这似乎有效(或者至少可以编译),但是在gcc中,它以我不理解的方式失败。尝试创建mySmallerArray时的编译器错误是:

use of deleted function myArrayType(myArrayType<T> &&)

......指着行尾的插入符号。换句话说,gcc似乎认为在调用'子数组运算符'时我实际上是在尝试调用一个移动构造函数,但我不能为我的生活看到它想要使用它的原因,或者为什么。 / p>

我是否遗漏了一些非常明显的东西,或者是否有人可以对此有所了解?

1 个答案:

答案 0 :(得分:1)

gcc正在做正确的事。

从operator()返回newObject,myArrayType的一个实例。这必须移动到变量mySmallerArray中。这是使用移动构造函数完成的,你没有。

您需要声明一个移动构造函数。

这个类有一个移动构造函数是有意义的 - 它可以将指针p从现有实例移动到新实例。