Ternary operator on auto_ptr content not working
I initialize an auto_ptr to NULL and later in the game I need to know if it has NULL or not to return it or a new copy.
I've tried this
auto_ptr<RequestContext> ret = (mReqContext.get() != 0) ? mReqContext : new RequestContext();
And several oth开发者_如何学编程er similar stuff casting and so, but g++ tries to invoke auto_ptrs nonexistent operator? (the ternary operator) instead of using RequestContext* for the ternary comparison.
Even if I cast it it doesn't work.
Any hint?
Edited the equal for non-equal
I suppose the situation is analogous to the following:
#include <iostream>
#include <memory>
int main()
{
std::auto_ptr<int> a(new int(10));
std::auto_ptr<int> b = a.get() ? a : new int(10);
}
And here's Comeau's very enlightening error message:
"ComeauTest.c", line 7: error: operand types are incompatible ("std::auto_ptr<int>"
and "int *")
std::auto_ptr<int> b = a.get() ? a : new int(10);
^
Ternary operator requires compatible types for both results, you can't have it return user-defined object in one case and a naked pointer in the other. NB! std::auto_ptr
takes a pointer in an explicit constructor, which means the ternary operator cannot implicitly convert the second argument to std::auto_ptr
And possible solution:
std::auto_ptr<int> b = a.get() ? a : std::auto_ptr<int>(new int(10));
mReqContext
is of type auto_ptr<RequestContext>
, right? Then the problem may be incompatible types on both sides of the :
because new RequestContext()
yields a RequestContext *
, but both must have a common type for the ternary operator to be usable.
Possible solutions: Either use
auto_ptr<RequestContext>(new RequestContext)
at the right side of the :
or use
mReqContext.get()
at the left side of the :
.
In both cases: Beware of the pointer ownership issues with auto_ptr
! The (raw) pointer in an auto_ptr
can be only be owned by a single auto_ptr
object, so both of my "simple" solutions may not be what you want (the first one clears out mReqContext
when it is non-zero, the second one doesn't but may lead to duplicate deletion of mReqContext
).
try
auto_ptr<RequestContext> ret;
ret.reset(new stuff here);
Did you try, breaking that up into two lines?
RequestContext *p = (mReqContext.get() == 0) ? mReqContext : new RequestContext();
auto_ptr<RequestContext> ret = p;
Have you tried putting it all into braces?
auto_ptr<RequestContext> ret =
(mReqContext.get() == 0) ? (mReqContext) : (new RequestContext());
Make sure you are not assigning pointer to the auto_ptr, this will not work. However, all these fragments compiling just fine:
#include <memory>
#include <string>
using namespace std;
int main(int argc, char * argv[] )
{
auto_ptr<int> pX;
pX.reset(pX.get() ? new int(1) : new int(2));
pX = auto_ptr<int>(pX.get() ? new int(1) : new int(2));
pX = auto_ptr<int>((pX.get()==NULL) ? new int(1) : new int(2));
return 0;
}
精彩评论