Reputation: 190659
I have a class AP
template<typename T>
class AP : public std::auto_ptr<T>
{
typedef std::auto_ptr<T> Super;
public:
AP() : Super() { }
AP(T* t) : Super(t) { }
AP(AP<T>& o) : Super(o) { }
};
And a function to return it.
namespace AIR {
namespace Tests {
namespace
{
AP<A> CreateGraph()
{
AP<A> top(A::Create("xyz").release());
...
return top;
}
AP<A> top;
top = CreateGraph();
When I compile the code
AP<A> top;
top = CreateGraph();
I got this error message
no match for ‘operator=’ in ‘top = AIR::Tests::<unnamed>::CreateGraph()()’
I added this operator to the AP class, but it doesn't work.
AP<T>& operator=(AP<T>& o) { (*(Super*)this) = o; return *this; }
What's wrong with the class?
top.reset(CreateGraph().release())
solved this issue.
Upvotes: 1
Views: 1223
Reputation: 354979
CreateGraph()
returns by value, thus a CreateGraph()
function call is an rvalue.
Because the std::auto_ptr
copy assignment operator takes its argument by non-const reference, the implicitly declared AP
copy assignment operator takes its argument by non-const reference.
A non-const reference can only bind to an lvalue, hence the error.
As I explained in an answer to one of your previous questions, if you want to have std::auto_ptr
-like copying (where the actual copy constructor takes its argument by non-const reference), you also need to implement something similar to std::auto_ptr_ref
.
I explain how std::auto_ptr
uses this helper class to allow copying of rvalues in the accepted answer to How could one implement std::auto_ptr
's copy constructor?
Upvotes: 4
Reputation: 2516
What if you replace
AP<A> top;
top = CreateGraph();
to
AP<A> top(CreateGraph());
Upvotes: 0