Question

I have a class with a copy constructor and move constructor, both of which report messages to stdout until I figure this problem out. When pushing a local object onto a vector, no constructor is ever called, leading to later problems. However, when I use std::move to tell it to use the move constructor instead of the copy constructor, everything works fine. Is this a bug, or am I misunderstanding how std::vector operates?

These are my object's constructors:

template <typename R>
inline Ref (const Ref<R> &other)
: m_ptr(other.m_ptr)
{
  LogDebugc("copy ctor ", long(other.m_ptr));
  Retain(m_ptr);
}

template <typename R>
inline Ref (Ref<R> &&other)
: m_ptr(other.m_ptr)
{
  LogDebugc("move ctor ", long(other.m_ptr));
  other.m_ptr = nullptr;
}

And here's where the problem occurs:

void SetState (State *state)
{
  // Keep a reference so we don't free the state by mistake
  Ref<State> ref (state);

  s_stateStack.clear();
  if (ref) {
    LogDebugc("pre push ", long(state));
    s_stateStack.push_back(ref);
    LogDebugc("post push ", long(state));
  }
}

I'm expecting to get the output...

[dbg] pre push 6415744
[dbg] copy ctor 6415744
[dbg] post push 6415744

...but instead, I'm getting...

[dbg] pre push 6415744
[dbg] post push 6415744

When I change the line where the state is pushed back, I get:

s_stateStack.push_back(std::move(ref));

[dbg] pre push 6415744
[dbg] move ctor 6415744
[dbg] post push 6415744

This is deeply confusing me.

Was it helpful?

Solution

template <typename R>
inline Ref (const Ref<R> &other)
: m_ptr(other.m_ptr)
{
  LogDebugc("copy ctor ", long(other.m_ptr));
  Retain(m_ptr);
}

That is not a copy constructor. As such, it's not being called.

§ 12.8 A non-template constructor for class X is a copy constructor if its first parameter is of type X&, const X&, volatile X& or const volatile X&, and either there are no other parameters or else all other parameters have default arguments

The compiler is using the implicitly generated copy constructor rather than the conversion constructor that you wrote.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top