This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++11 status.

### 1138. Unusual return value for `operator+`

Section: 23.4.4.1 [string.op.plus] Status: C++11 Submitter: Alisdair Meredith Opened: 2009-06-12 Last modified: 2021-06-06

Priority: Not Prioritized

View all issues with C++11 status.

Discussion:

Many of the `basic_string operator+` overloads return an rvalue-reference. Is that really intended?

I'm considering it might be a mild performance tweak to avoid making un-necessary copies of a cheaply movable type, but it opens risk to dangling references in code like:

>     auto && s = string{"x"} + string{y};

and I'm not sure about:

>     auto s = string{"x"} + string{y};

[ 2009-10-11 Howard updated Returns: clause for each of these. ]

[ 2009-11-05 Howard adds: ]

> Moved to Tentatively Ready after 5 positive votes on c++std-lib.

Proposed resolution:

Strike the `&&` from the return type in the following function signatures:

> 23.4 [string.classes] p2 Header Synopsis

> >     template<class charT, class traits, class Allocator>
> >       basic_string<charT,traits,Allocator>&&
> >         operator+(basic_string<charT,traits,Allocator>&& lhs,
> >                   const basic_string<charT,traits,Allocator>& rhs);

> >     template<class charT, class traits, class Allocator>
> >       basic_string<charT,traits,Allocator>&&
> >         operator+(const basic_string<charT,traits,Allocator>& lhs,
> >                   basic_string<charT,traits,Allocator>&& rhs);

> >     template<class charT, class traits, class Allocator>
> >       basic_string<charT,traits,Allocator>&&
> >         operator+(basic_string<charT,traits,Allocator>&& lhs,
> >                   basic_string<charT,traits,Allocator>&& rhs);

> >     template<class charT, class traits, class Allocator>
> >       basic_string<charT,traits,Allocator>&&
> >         operator+(const charT* lhs,
> >                   basic_string<charT,traits,Allocator>&& rhs);

> >     template<class charT, class traits, class Allocator>
> >       basic_string<charT,traits,Allocator>&&
> >         operator+(charT lhs, basic_string<charT,traits,Allocator>&& rhs);

> >     template<class charT, class traits, class Allocator>
> >       basic_string<charT,traits,Allocator>&&
> >         operator+(basic_string<charT,traits,Allocator>&& lhs,
> >                   const charT* rhs);

> >     template<class charT, class traits, class Allocator>
> >       basic_string<charT,traits,Allocator>&&
> >         operator+(basic_string<charT,traits,Allocator>&& lhs, charT rhs);

> [string.op+]

> >     template<class charT, class traits, class Allocator>
> >       basic_string<charT,traits,Allocator>&&
> >         operator+(basic_string<charT,traits,Allocator>&& lhs,
> >                   const basic_string<charT,traits,Allocator>& rhs);

> > > Returns: `std::move(lhs.append(rhs))`

> >     template<class charT, class traits, class Allocator>
> >       basic_string<charT,traits,Allocator>&&
> >         operator+(const basic_string<charT,traits,Allocator>& lhs,
> >                   basic_string<charT,traits,Allocator>&& rhs);

> > > Returns: `std::move(rhs.insert(0, lhs))`

> >     template<class charT, class traits, class Allocator>
> >       basic_string<charT,traits,Allocator>&&
> >         operator+(basic_string<charT,traits,Allocator>&& lhs,
> >                   basic_string<charT,traits,Allocator>&& rhs);

> > > Returns: `std::move(lhs.append(rhs))` [Note: Or equivalently `std::move(rhs.insert(0, lhs))` — end note]

> >     template<class charT, class traits, class Allocator>
> >       basic_string<charT,traits,Allocator>&&
> >         operator+(const charT* lhs,
> >                   basic_string<charT,traits,Allocator>&& rhs);

> > > Returns: `std::move(rhs.insert(0, lhs))`.

> >     template<class charT, class traits, class Allocator>
> >       basic_string<charT,traits,Allocator>&&
> >         operator+(charT lhs, basic_string<charT,traits,Allocator>&& rhs);

> > > Returns: `std::move(rhs.insert(0, 1, lhs))`.

> >     template<class charT, class traits, class Allocator>
> >       basic_string<charT,traits,Allocator>&&
> >         operator+(basic_string<charT,traits,Allocator>&& lhs,
> >                   const charT* rhs);

> > > Returns: `std::move(lhs.append(rhs))`.

> >     template<class charT, class traits, class Allocator>
> >       basic_string<charT,traits,Allocator>&&
> >         operator+(basic_string<charT,traits,Allocator>&& lhs, charT rhs);

> > > Returns: `std::move(lhs.append(1, rhs))`.