Boost logo

Boost :

Subject: Re: [boost] [utility] string_ref construction from rvalue reference to string
From: Andrey Davydov (andrey.a.davydov_at_[hidden])
Date: 2014-08-03 08:27:13


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.

On Sat, Aug 2, 2014 at 2:46 AM, Nathan Crookston <nathan.crookston_at_[hidden]
> wrote:

> I suppose that would break cases like:
>
> std::string getStr();
> print(std::string_ref sr) { std::cout << sr << std::endl; }
>
> print(getStr());
>
> Causing people to have to write print(getStr().c_str()).
>

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`. 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.

On Sat, Aug 2, 2014 at 2:24 AM, Marshall Clow <mclow.lists_at_[hidden]> wrote:

> It would mean that string_ref will no longer compile under C++03.
>

Of course, I propose to hide it under corrsponding ifdefs. Something like
this:
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
    #ifndef BOOST_NO_CXX11_DELETED_FUNCTIONS
        template<typename Allocator>
        basic_string_ref(std::basic_string<charT, traits, Allocator> &&) =
delete;
    #else
    private:
        template<typename Allocator>
        basic_string_ref(std::basic_string<charT, traits, Allocator> &&);
    public:
    #endif

        template<typename Allocator>
        basic_string_ref(const reference_wrapper< const std::basic_string<
charT, traits, Allocator> > rw)
            : ptr_(rw.get().data())
            , len_(rw.get().length())
        {}
#endif

-- 
Andrey

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