我有一些不可复制的课程。我没有调用任何复制操作符或构造函数,并且此代码编译良好。但后来我升级到Visual Studio 2010 Ultimate而不是Professional。现在编译器正在调用复制构造函数 - 即使应该调用移动构造函数。例如,在以下代码段中:
inline D3D9Mesh CreateSphere(D3D9Render& render, float radius, float slices) {
D3D9Mesh retval(render);
/* ... */
return std::move(retval);
}
错误:无法创建复制构造函数,因为该类是不可复制的。但是,我非常明确地提出了它。
编辑:
class D3D9Mesh
: public Monitor<D3D9Mesh>
{
public:
std::unique_ptr<ID3DXMesh, COMDeleter> Mesh;
std::unique_ptr<ID3DXBuffer, COMDeleter> Adjacency;
inline D3D9Mesh(D3D9Render& ref)
: Monitor<D3D9Mesh>(&ref)
{
}
};
其中Monitor是一个可复制/等的简单类。这是unique_ptrs,显然不是编译器的犹太人。
监视器的代码:
class D3DCommon {};
template<typename T> class Monitor : public D3DCommon {
protected:
D3D9Render* render;
Monitor(D3D9Render* ptr)
: render(ptr) {
render->AddPointer(static_cast<T*>(this));
}
Monitor(Monitor&& ref) {
render->AddPointer(static_cast<T*>(this));
}
Monitor(const Monitor& ref) {
render->AddPointer(static_cast<T*>(this));
}
~Monitor() {
render->RemovePointer(static_cast<T*>(this));
}
public:
D3D9Render& GetRender() {
return *render;
}
};
答案 0 :(得分:1)
这很奇怪。你的D3D9Mesh课程是如何实施的? 以下代码为vs2010终极版编译好了:
#include <iostream>
struct S
{
S(){std::cout << "ctor\n";}
S(S&&){std::cout << "move ctor\n";}
S& operator=(S&&){std::cout << "move op=\n";return *this;}
private:
S(const S&);
S& operator=(const S&);
};
inline S CreateSphere()
{
S s;
return s;
}
int main()
{
S s = CreateSphere(); // NRVO
s = CreateSphere(); // move
}
PS:如果“something”是在函数中创建的局部变量,则不要写return std :: move(something)。编译器已经知道从函数返回一个局部变量是一个临时值(一个右值)。使用std :: move重新进行自我调整不会让它更好地移动,但它会阻止vs2010进行一些优化,例如NRVO。
答案 1 :(得分:1)
MSVC不执行隐式移动构造函数。你需要自己做:
class D3D9Mesh
: public Monitor<D3D9Mesh>
{
public:
inline D3D9Mesh(D3D9Render& ref)
: Monitor(&ref) // don't need to re-state template argument, by the way
{
}
D3D9Mesh(D3D9Mesh&& other)
: Monitor(std::move(other))
{}
};
现在它可以移动了。