[cfe-dev] Parser Stmt/Expr Owning Pointer
Sebastian Redl
sebastian.redl at getdesigned.at
Tue Dec 9 02:05:22 PST 2008
Howard Hinnant wrote:
> On Dec 8, 2008, at 9:04 PM, Chris Lattner wrote:
>
>
>>> I personally don't find move() strange at all, but then I've been
>>> preoccupied with move semantics and their emulation since I learned
>>> of the concept two years ago. (Note: with proper C++0x moving,
>>> there'll be no need to call move() anymore. However, due to the
>>> reference binding rules of C++03, the only way to achieve this is to
>>> allow the highly unsafe practice of moving from const references.)
>>>
>> Yep yep, rvalue refs are very nice. Unfortunately we probably can't
>> actually *use* them in llvm/clang until they are widely deployed in
>> vendor compilers. :( It sucks to have to write portable code.
>>
>> What do other people think about this name?
>>
>
> It shouldn't be surprising that I prefer move(). In fact I'd prefer a
> namespace scope move, but I have no real problem with the member
> move.
I'm looking forward to seeing your tricks to allow a namespace scope
move bind to temporaries but not const lvalues. I don't know how to do
it, so my move() is a member.
> Sebastian's ASTOwner::move() returns a ASTMove. I'm not yet positive
> what it will do with:
>
> {
> ASTOwner<&Action::DeleteStmt> p(actions);
> p.move();
> } // leaked?
>
Nope. ASTMove emulates an rvalue reference. It's patterned after
Boost.Thread's move helper.
> And has a disadvantage that if passed to a templated function, the
> wrong type gets deduced.
>
True. I find the likelihood of this in the Clang source low.
> Fwiw I'm pretty close to a C++03 unique_ptr that is passing all my
> tests so far. It needs a <type_traits> (which I also have). It
> doesn't have the "moves from const" bug that my previous emulation
> attempt had.
>
I'd love to see it.
> template <void (Action::*Destroyer)(void*)>
> class ASTDeleter {
> Action &Actions;
>
> // Reference member prevents copy assignment.
>
> public:
> explicit ASTDeleter(Action &actions) : Actions(actions) {}
>
> void operator()(void* Node) {
> (Actions.*Destroyer)(Node); // no null check needed
> }
> };
>
Is there a specific reason the constructor can't be implicit? Then you
could leave out the long typedef here:
> ExprGuard ex((void*)1, ExprGuard::deleter_type(Actions));
>
and just write ExprGuard ex(ptr, Actions).
Also, can I trick your unique_ptr to give up its raw pointer after it
has been moved from? For convenience in the transition phase, that would
be invaluable. In my current implementation you can do:
void takesOwnershipButHasNotBeenConvertedToBeSmart(ExprTy*);
ExprOwner ptr(getExprFromSomewhere());
takesOwnershipButHasNotBeenConvertedToBeSmart(ptr.move());
The important part is that it's always move(), even after converting the
function to take an ExprOwner.
Sebastian
More information about the cfe-dev
mailing list