I have a Visual Studio 2008 C++ project with a class that manages a resource that cannot be copied. I have implemented transfer-by-reference-structure semantics (ala std::auto_ptr).
class Test;
struct Test_Ref
{
Test& ref_;
Test_Ref( Test& t ) : ref_( t ) { };
private:
Test_Ref& operator=( Test_Ref const& );
}; // struct Test_Ref
class Test
{
public:
explicit Test( int f = 0 ) : foo_( f ) { };
Test( Test& other ) : foo_( other.Detach() ) { };
Test& operator=( Test& other )
{
foo_ = other.Detach();
return *this;
};
Test( Test_Ref other ) : foo_( other.ref_.Detach() ) { };
Test& operator=( Test_Ref other )
{
foo_ = other.ref_.Detach();
return *this;
};
operator Test_Ref() { return Test_Ref( *this ); };
private:
int Detach()
{
int tmp = foo_;
foo_ = 0;
return tmp;
};
// resource that cannot be copied.
int foo_;
}; // class Test
Unfortunately, when I use this pattern with a library that uses placement-new, I get a compiler error:
.\test.cpp(58) : error C2558: class 'Test' : no copy constructor available or copy constructor is declared 'explicit'
.\test.cpp(68) : see reference to function template instantiation 'void Copy<Test>(T *,const T &)' being compiled
with
[
T=Test
]
For example:
template< class T > inline void Copy( T* p, const T& val )
{
new( p ) T( val );
}
int _tmain( int /*argc*/, _TCHAR* /*argv*/[] )
{
Test* __p = new Test();
Test __val;
Copy( __p, __val );
return 0;
}
How can I modify Test such that it can be used with placement new and still retain its ownership semantics?
Thanks,
PaulH
Focusing on the
mainfunction, as that should indicate your intended semantics, there are two big problems: First, you are not allocating memory, which means that if the compiler would process the code, it would cause UB (would try to call the constructor ofTestover theNULLaddress in the placement new operation.The other issue is well known to users of
std::auto_ptr: The signature of the copy constructor takes a non-const reference, and that means that you cannot call it on a const object. On the other end you are trying to call the copy constructor inside theCopytemplate that promised not to change the object referenced by the second argument:Finally, I am not sure if due to copying into the question, but I am not sure of what your intentions are with the reference wrapper class that you are providing in the beginning, so you might want to clarify.