operator+
Section: 27.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:
27.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 equivalentlystd::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))
.