开发者

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;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜