1

I have a string class. Some operators return references, others return values. Only the ones that return values can take advantage of the rvalue copy constructor or rvalue assignment operator.

I would like the rvalue operator to be called on a reference to an rvalue.

Given these:

String(const TCHAR* sz);
String(const String& s);    
String& operator+=(const TCHAR* sz);    
String& operator=(String&& r);

And this code:

String x;
x = (String("fred") += "foo");

It calls the copy constructor, the += operator, but then the COPY CONSTRUCTER again. I want it to call the rvalue assignment operator!

I added this:

String(String&& r) 

And that makes no difference.

EDIT: I confirmed that if I make my += operator return a value, the rvalue assignment operator will be called. I have done a lot of performance testing and doing this makes everything a lot slower.

ildjarn
  • 62,044
  • 9
  • 127
  • 211
johnnycrash
  • 5,184
  • 5
  • 34
  • 58
  • Gosh darn it, I got two correct answers. I don't know what to do! – johnnycrash Dec 07 '12 at 23:53
  • If you're looking for high-efficiency expression combinations, you probably want to look into expression templates. [Boost.Proto](http://www.boost.org/doc/libs/1_52_0/doc/html/proto.html) will help you there. – GManNickG Dec 08 '12 at 00:09

1 Answers1

2

You can't easily differentiate between a "genuine" rvalue and an rvalue reference, but you don't seem to have a motivation to do so. Your overload is fine.

The problem is that rvalue-ness is lost by the += operator. There are three solutions:

  1. Manually make it an rvalue: x = std::move(String("fred") += "foo");
  2. Use non-member overloads. I generally prefer this because it resolves other issues such as applying conversion functions to the left-hand side of a += expression.

    String& operator+=(String &lhs, const TCHAR* sz);
    String&& operator+=(String &&lhs, const TCHAR* sz);
    
  3. Use reference qualifiers so that operator+= returns an rvalue when applied to an rvalue. Few compilers support this yet.

    String& operator+=(const TCHAR* sz) &;
    String&& operator+=(const TCHAR* sz) &&;
    
Potatoswatter
  • 134,909
  • 25
  • 265
  • 421
  • @GManNickG I gotta go, and I've never looked at Boost.Proto so the advantage is yours :P but I will later – Potatoswatter Dec 07 '12 at 23:33
  • my compiler can't handle it. I'm using vc2010, maybe the newer vc can do it. – johnnycrash Dec 07 '12 at 23:43
  • @johnnycrash #2 should work with any compiler, it's not C++11 or anything. Those declarations either don't go inside `class`, or should be marked `friend` if they are. – Potatoswatter Dec 08 '12 at 00:29
  • Sorry, I should have said the last form. – johnnycrash Dec 08 '12 at 00:54
  • … oh, I should mention that to be really non-C++11, you would just erase both `&&`'s from #2. But the resulting declaration would really just be `operator+`, which is effectively the semantics that result in any case. I'll try to remember to edit later and mention Boost.proto. – Potatoswatter Dec 08 '12 at 05:30
  • Meh, since GMan deleted his answer, I'll just drop my link here, for the explanation what the `&` and `&&` after the functions do: [What is "rvalue reference for *this"?](http://stackoverflow.com/q/8610571/500104) Hope you don't mind. :) – Xeo Dec 08 '12 at 12:09