mardi 7 novembre 2023

Why did compiler add static_cast to const rvalue ref if an object has a user defined/declared destructor

As per following example

struct Apple  {
  ~Apple() {};
};

int main()
{
    Apple a1;
    Apple a2 = std::move(a1);
}

and example

struct Apple  {
  ~Apple() = default;
};

int main()
{
    Apple a1;
    Apple a2 = std::move(a1);
}

with following transformation done by compiler

struct Apple
{
  inline ~Apple() /* noexcept */ = default;
  // inline constexpr Apple() noexcept = default;
  // inline constexpr Apple(const Apple &) noexcept = default;
};



int main()
{
  Apple a1;
  Apple a2 = Apple(static_cast<const Apple &&>(std::move(a1)));
  return 0;
}

compiler added static_cast<const Apple &&> in

Apple a2 = Apple(static_cast<const Apple &&>(std::move(a1)));

if there was a user defined/declared destructor. It was not the case as per example

struct Apple  {
};

int main()
{
    Apple a1;
    Apple a2 = std::move(a1);
}

where the transformed code snippet by compiler was

struct Apple
{
  // inline constexpr Apple() noexcept = default;
  // inline constexpr Apple(Apple &&) noexcept = default;
};



int main()
{
  Apple a1;
  Apple a2 = Apple(std::move(a1));
  return 0;
}

if no destructor is defined/declared by user.

Why was it the case?

PS People tends to think that it was because with user declared/defined destructor, compiler will only implicitly generate copy constructor but not move constructor. That is correct. But even only with copy constructor and without move constructor, const Apple& is able to be bound to rvalue ref and static_cast<const Apple&&> is not necessary for the code to compile, correct?

Aucun commentaire:

Enregistrer un commentaire