我正在尝试编写一个非常简单的数组类,其函数返回自身的子部分。展示它比解释更容易......
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>
我是否遗漏了一些非常明显的东西,或者是否有人可以对此有所了解?
答案 0 :(得分:1)
gcc正在做正确的事。
从operator()返回newObject,myArrayType的一个实例。这必须移动到变量mySmallerArray中。这是使用移动构造函数完成的,你没有。
您需要声明一个移动构造函数。
这个类有一个移动构造函数是有意义的 - 它可以将指针p从现有实例移动到新实例。