mariusbancila / stduuid

A C++17 cross-platform implementation for UUIDs
MIT License
758 stars 112 forks source link

Constructing `const uuid` from another #71

Open mwerezak opened 2 years ago

mwerezak commented 2 years ago

I am unable to construct a const uuid from another uuid (i.e. making a const copy), seemingly due to the lack of a copy constructor.

class Example {
public:
   Example(const uuid &x): y(x) { }
private:
   const uuid y;
};

The compiler wants to use operator= but it cannot, because the destination is const.

If I insert into uuid.h:

   class uuid
   {
   public:
       //...
       uuid(const uuid &src) noexcept : uuid(src.data) {}  // new copy constructor
       //...
   };

Then it compiles. Is there a reason uuid does not have a copy constructor?

justend29 commented 1 year ago

@mwerezak I'm not sure what your usage of class Example is, but the following code tests its construction, copy construction, move construction, copy assignment, and move assignment. GCC13.2.1 was used with stduuid v1.2.2. If this doesn't help your issue, could you provide details about what your usage of Example is, please?

In the following example, you'll notice that the member y has been made non-const, as types with const members cannot be assigned in general. Consider that assignment involves first having a destination, then overwriting it, thereby changing the members (non-const operation). All but the assignments would still compile if y was const, as it is in your example.

#include <stduuid/uuid.h>
#include <iostream>

class Example {
 public:
  Example(const uuids::uuid& x) : y{x} {}

  const uuids::uuid& get_uuid() const {
    return y;
  }

 private:
  uuids::uuid y;
};

int main() {
  const auto& arbitrary_uuid = uuids::uuid_namespace_url;
  const Example ex{arbitrary_uuid};

  const Example copy_constructed{ex};
  const Example move_constructed{Example{arbitrary_uuid}};

  Example copy_assigned{arbitrary_uuid};
  copy_assigned = ex;

  Example move_assigned{arbitrary_uuid};
  move_assigned = Example{arbitrary_uuid};

  // use Examples to ensure they're not just being optimized out
  std::cout << uuids::to_string(ex.get_uuid()) << '\n'
            << uuids::to_string(copy_constructed.get_uuid()) << '\n'
            << uuids::to_string(copy_assigned.get_uuid()) << '\n'
            << uuids::to_string(move_assigned.get_uuid()) << std::endl;
}