Boost logo

Boost :

From: Andrey Melnikov (melnikov_at_[hidden])
Date: 2005-07-11 12:33:58


David Abrahams wrote:
> Felipe Magno de Almeida <felipe.m.almeida_at_[hidden]> writes:
>
> <snip> a giant message>
>
>>>I can return a fresh NonCopyable and NonDefaultConstructible object from
>>>a function without often expensive heap operations.
>>
>>Isnt that the boost::ref goal? Or am I missing something?
>>
>
> <snip> some more of the message

David, you are the man. Now I can answer this message! Well, I'm going
to give rise to a new giant... Readers, please bother to crop it when
replying.

 From Introduction section at http://www.boost.org/doc/html/ref.html I
see that boost::ref I see that is isn't the boost::ref goal.

Boost.Ref can save some CPU cycles only if I deal with hostile pieces of
code such as std::foreach() which refuse to work with references. If I
write all code myself, I don't need boost::ref. In complex cases
type_traits can help me and compiler to handle references correctly.

Consider the following rather typical scenarios when you return a
std::string. These examples are a bit artificial, but in some
circumstances default construction, dynamic memory and copying can be
computationally too expensive or not available at all.

The following versions are not ideal:

std::string foo()
{
        return "bar";
}
...
std::string bar = foo();
--------
void foo( std::string & bar)
{
     bar = "bar" ;
}
...
std::string bar;
foo(bar);
----------
std::string * foo()
{
     return new std::string("bar");
}
...
std::auto_ptr<std::string> bar = foo();
-----------

Each of them includes some extra operations which aren't necessary.
Version 1 is terrible, version 2 uses an extra default construction,
version 3 uses an extra memory allocation.

Here is a better version:

void foo( std::string * bar )
{
    new (bar) std::string("bar");
}
...
char bar_placeholder[sizeof(std::string];
std::string *bar = reinterpret_cast<std::string*>(bar_placeholder);
foo(bar);
...
bar->~std::string();

It uses just one constructor call, no extra default constructors and no
dynamic memory allocation. So far after reading the documentation, it
seems to me that boost::optional provides a nice encapsuation for this
bulk of code.

void foo(boost::optional<std::string> & bar)
{
        bar = boost::in_place("bar");
}
...
boost::optional<std::string> bar;
foo(bar);

But unlike raw code, this approach also creates a copy of "bar" char*
stored in a temporary factory object.

Does boost::optional have a way to avoid these temporaries too? Does it
have something like

bar.in_place("bar); or in_place(bar, "bar"); ?

Andrey


Boost list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk