
I was careful to say equivalent, not equal, since even when things don't have any kind of comparison operator, C++03 still has the requirement that a copy of an object (whether from copy-construction or assigned) must be equivalent to the original, so the concept is there.
Yes, I understand that you've been talking about equivalency. My point was that I was under impression you were extending (unduly IMHO) the equivalency (a requirement for the copy contructor) onto comparability as you were stressing that for the following the first 10 entries will end up different from the last 10: v.resize(10, uuid()) v.resize(20, uuid()) The equivalency requirement is about copying those second parameters into 'v'. And we are safe there, aren't we? There is no mention of all 20 being comparably equal (and in general terms we cannot expect that as op==() is not a given). Yes, it indeed looks somewhat weird if we are to treat classes as they were integers. Still, that "weirdness" does not prevent uuid with "my" behavior to be a regular type as per Stepanov: "... equality is defined through a pair-wise equality of the corresponding parts. I call objects satisfying such laws regular."
Anyways, did you have any comments on my view of UUIDs as resource handles?
Well, I think you have a point about UUIDs as resource handles. To me that view is a *deployment* view (like a key in std::map can be interpreted as a "resource handler", "pointer" to the actual resource). On that somewhat architectural level the notion of a "pointer" (or "resource handler") is obviously very different from and much broader than "my" view -- the *behavioral* view of the class itself. What I'd like to do in the discussion is to somewhat step back and clarify my initial goal. I "jumped" in with a clear intention to look at the review from the average user point of view. That is the position many are overwhelmingly in (using myriads of libraries developed by others). Therefore, I intentionally wanted to limit myself to the interface and the interface through the user's (not the developer's) eyes. From that point of view I felt that it was important to stay focused on the interface so that is complete but minimal, consistent and intuitive, unambiguous, with the minimum of new vocabulary and minimum of coupling. That's why I was happy to see conversions to/from string branched off into an orthogonal functionality (lexical_cast). That's why I would not want to see generators convertible into or aware of uuids. That's why I'd like to see all constructors behaving consistently and by the book. That's why I'd like to see a *special* uuid::nil() created via different "special" and explicit means. That's why I'd like to see the most convenient deployment operator (the def. cnstr) behaving as-others and assigned to the most used deployment pattern (IMHO of course). Now if this primary goal contradicts some subtle behavior (which I am convinced of :-) ), let's work around that to accommodate *both* sides (in fact, I'd still favored the user side as the user will be ultimately deciding the success/failure of our effort). With regard to the default constructor it seems like disabling it would be the best compromise. I hope we won't be arguing that all classes must have the default constructor so that we could use operator[] on std::map<string, some-class>. Best, V.