tags:

views:

225

answers:

6

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 other 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

+1  A: 

try

auto_ptr<RequestContext> ret;
ret.reset(new stuff here);
AlexKR
It's the same, the right side of the assignation is the problem, not the left one.
Arkaitz Jimenez
A: 

Did you try, breaking that up into two lines?

RequestContext *p = (mReqContext.get() == 0) ? mReqContext : new RequestContext();
auto_ptr<RequestContext> ret = p;
RED SOFT ADAIR
A: 

Have you tried putting it all into braces?

auto_ptr<RequestContext> ret =
    (mReqContext.get() == 0) ? (mReqContext) : (new RequestContext());
mxp
The braces are not a problem, it's the different types on the sides of :
sbk
Yeah, since UncleBens' answer, I know that, too. I was just guessing like some others here...
mxp
A: 

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;
}
AlexKR
+2  A: 

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).

hjhill
+19  A: 

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));
UncleBens