I'm not a v8 expert, but I think I can answer this.
On Fri, Jun 24, 2011 at 5:07 PM, Stephan Beal <[email protected]> wrote:
> Hi, gurus!
> i've come into a bit of a weird situation:
> i'm writing template-based generic functions which forward v8::Arguments
> args to native functions. i'm adding Unlocker support so clients can say
> "it's okay to unlock v8 while this function is running" when they bind the
> functions. i've come into a corner case in my design where i literally
> cannot scope a return value properly vis-a-vis Unlocker:
> T rv
> {
> Unlocker unl;
> rv = theFunction( ... );
> }
> return rv;
> that works for most cases but does not work when T is a reference type (or
> otherwise cannot be default-initialized).
You can solve the reference and const issues with type traits.
If its a reference, you can remove using remove_reference<T>::type.
Similarly with remove_const<T>::type. This is available in
tr1/C++0x/boost. It's also pretty easy to write these type traits
metafunctions yourself if you don't want to depend on tr1/C++0x/boost.
If you don't want to require T to be default constructable, you can't
create rv on the stack given your scoping requirement.
Here's a possible solution:
typedef std::remove_reference<T>::type T2;
typedef std::remove_const<T2>::type T3;
std::auto_ptr<T3> rv_ptr;
{
Unlocker unl;
rv_ptr = new T3(theFunction( ... ));
}
return *rv_ptr;
Notes: You lose return value optimization with this. If you just
require T be default constructable, its more efficient.
> i can work around it, but i need to know if this is legal:
> Unlocker unl;
> T rv( theFunction(...) );
> unl.~Unlocker(); // <----- this part
> return rv;
> i.e. i need to destruct the Unlocker before it goes out of scope.
> Is it legal for me to do this or will i somehow hose Unlocker's assumptions?
Your destructor will be called twice, which will probably blow up your program.
Um... Technically there is a way to call the destructor manually
without blowing things up, and also get back RVO without requiring T
be default constructable. I'm hesitant to say this, because this is
probably way more complicated than you are bargaining for. My advice
is to ignore what I say next and just require T be default
constructable.
If you want to call the destructor manually, you need to construct the
object with "placement new" on a properly aligned buffer. This is an
advanced feature, to put it lightly.
Read this thoroughly before even thinking about doing this:
http://www.parashift.com/c++-faq-lite/dtors.html
--
v8-users mailing list
[email protected]
http://groups.google.com/group/v8-users