Boost logo

Boost :

Subject: Re: [boost] [utility] string_ref construction from rvalue reference to string
From: Agustín K-ballo Bergé (kaballo86_at_[hidden])
Date: 2014-08-03 10:06:32


On 03/08/2014 09:27 a.m., Andrey Davydov wrote:
> On Sat, Aug 2, 2014 at 2:34 AM, Agustín K-ballo Bergé <kaballo86_at_[hidden]
>> wrote:
>
>> You wouldn't generally use `string_ref`s as automatic variables or members.
>>
>
> I can't confirm or refute this statement using code of Boost, because
> `boost::string_ref` has been used a little so far. But results of "grep
> StringRef" inside LLVM code show that StringRef's are used often as
> automatic variables. And in addition to explicitly defined class members
> there are another dangerous `string_ref` use cases, namely lambda capturing
> value and `bind` argument.

LLVM has some memory management that could be considered extreme, and it
does things to avoid even a single allocation (for good reason).
Nevertheless, you'll note that I said "wouldn't generally", and not
"can't", "won't" or "dangerous".

There's nothing specially dangerous about `string_ref` to temporaries,
or as members. In order to use `string_ref`, even for the simplest of
use cases, you have to guarantee that the referred content will outlive
it. If you use a `string_ref` as a function parameter, the language will
guarantee that for you, regardless of the value category of the
argument. Otherwise, it's "dangerous" as in you have think what you are
doing.

I took your idea a step further, and implemented your proposed change to
`StringRef`. I got hundreds of compilation errors. Most of them stemmed
from construction of `StringRef` from temporaries, not explicitly as in
your example, but as arguments to functions. There where other sources
of errors, like comparisons between `StringRef` and a temporary.

> It's possible to add `string_ref(reference_wrapper<const std::string>)`
> constructor to allow people write `print(boost::cref(getStr()))` instead of
> `print(getStr().c_str())`. The first version is more efficient and less
> ugly IMO. I want to emphasize, that it should be `boost::cref` not `std::
> cref`, because `std::cref(std::string &&) = deleted`.

Not as of 1.56.

> It seems to me, that
> prohibition of constructing `reference_wrapper` from temporary in C++11 is
> one more argument in favor of my proposition to prohibit `string_ref`
> construction from temporary string.

A `reference_wrapper` is a wrapper for an lvalue reference. The
motivation to prohibit binding to an rvalue is a different one.

Regards,

-- 
Agustín K-ballo Bergé.-
http://talesofcpp.fusionfenix.com

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