0

Suppose I have 3 classes: Base, Derived and Chunky. Derived is derived from Base, and Base has a member of type Chunky (Chunky is large, and I don't want to copy it unless I have to).

Here is Base, assume that we cannot change it in any way (no, we can't create a constructor for it):

class Base
{
public:
  Chunky monkey;
}

Derived looks something like this:

class Derived : public Base
{
  // option 1
  Derived(Chunky const& monkey)
  {
    this->monkey = monkey;
  }

  // option 2
  Derived(Chunky monkey)
  {
    // does this do anything useful, or am I wasting my time by calling std::move?
    this->monkey = std::move(monkey);
  }
}

I like option 2 better because the intent is clearer and I don't have to create a reference value, but do we still have the benefit of std::move when monkey can't be initialised in constructor initializer list? How would you solve this problem (again assuming Base can't change)?

In case anyone wants to know, monkey in this case is an std::function, and this discussion didn't really answer my question.

Community
  • 1
  • 1
quant
  • 21,507
  • 32
  • 115
  • 211
  • Can monkey be a pointer (use new, delete etc.) you can pass around the and even make NULL if you don't need it? – Atle Oct 17 '13 at 10:39
  • @Atle no, `Chunky` is actually of type `std::function` in my case. Besides, I'm not allowed to modify `Base` so it has to be a value. – quant Oct 17 '13 at 10:41
  • std::function is not that large, and can be copied. So, what is the problem? – BЈовић Oct 17 '13 at 10:44
  • @BЈовић how big is it? I have no idea... – quant Oct 17 '13 at 10:46
  • 1
    The assignment in option 1 will copy the object, I guess. – Atle Oct 17 '13 at 10:53
  • 32 bytes on my system (64bit ubuntu) – BЈовић Oct 17 '13 at 10:55
  • @BЈовић: Size of `std::vector` is also small, but that does not mean that copying is cheap. – Juraj Blaho Oct 17 '13 at 11:09
  • @JurajBlaho No, it doesn't, since it depends on the particular implementation. If the implementation do a shallow copy - it is going to be very cheap. Now copying `std::function` should not be expensive, unless it is implemented in a very crappy way – BЈовић Oct 17 '13 at 11:13
  • @BЈовић: Shallow copy may not be enough. Consider mutable capture by value: http://ideone.com/r3HjZx – Juraj Blaho Oct 17 '13 at 11:23
  • @JurajBlaho Never mind that vector thing. Copying std::function is cheap. – BЈовић Oct 17 '13 at 11:40
  • @BЈовић: Yes it may be fast, but it does depend on the actual function stored. With expensive to copy captured variables the difference between move and copy is big: http://ideone.com/2ZiBFq – Juraj Blaho Oct 17 '13 at 12:03

1 Answers1

1

Yes, there is still the benefit of move in the second case, even if the move is not in the member initializer list. But be aware that in this case move assignment is used instead of move construction, so the Chunky type needs to support that. As Chunky is std::function it is OK.

The second option seems preferable as it may avoid copy compared to the first option. In the better case it needs just two moves, but in the worse case a copy followed by a move is performed. The first option always needs a single copy.

Juraj Blaho
  • 13,301
  • 7
  • 50
  • 96