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

Unexpected invocation of deleted move constructor by gcc

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

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 似乎认为在调用 'subarray operator' 时我实际上是在尝试调用一个移动构造函数,但我终究无法看到它想在哪里使用它,或者为什么。

我是否遗漏了一些非常明显的东西,或者任何人都可以阐明这一点吗?

gcc 正在做正确的事。

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

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

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