Re: [boost] [uuid] Interface

It seems I did it again. :--( Just noticed that I misread the following excerpt of Scott's email. Apologies and corrections further below.
Take, for example, a map<string, uuid>. No default constructor means that you can't use operator[],
First, my preference is to *have* the default constructor -- we disagree on its behavior as I'd like the default constructor to *be part* of the constructors family (constructing a valid object) and you insist on the default constructor being an exception. The latter is not how the language interprets the default constructor. Therefore, me not happy. IMHO that deviation of the meaning from the letter of the language is unacceptible. Second, even if I cannot use operator[], so what? std::fstream has no default constructor. std::list has no operator[], std::vector has no push_front(). That did not stop anyone from using those classes. What the lack of those "features" achieved instead is that it most likely saved a few people from shooting themselves in a foot. Best, V.

on Fri Dec 19 2008, "Vladimir Batov" <batov-AT-people.net.au> wrote:
It seems I did it again. :--( Just noticed that I misread the following excerpt of Scott's email. Apologies and corrections further below.
Take, for example, a map<string, uuid>. No default constructor means that you can't use operator[],
First, my preference is to *have* the default constructor -- we disagree on its behavior as I'd like the default constructor to *be part* of the constructors family (constructing a valid object) and you insist on the default constructor being an exception.
I think the terminology "valid object" is misleading here. A NULL pointer is valid. An uninitialized pointer is... marginally valid. I don't think anyone is suggesting that uuid() should produce an object that can only be assigned to or destroyed.
The latter is not how the language interprets the default constructor.
I can't imagine what you mean by that.
Therefore, me not happy. IMHO that deviation of the meaning from the letter of the language is unacceptible.
Second, even if I cannot use operator[], so what? std::fstream has no default constructor. std::list has no operator[], std::vector has no push_front(). That did not stop anyone from using those classes. What the lack of those "features"
Do you really mean to imply that push_front, operator[], et. al. are not legitimate features? -- Dave Abrahams BoostPro Computing http://www.boostpro.com

I think the terminology "valid object" is misleading here. A NULL pointer is valid. An uninitialized pointer is... marginally valid. I don't think anyone is suggesting that uuid() should produce an object that can only be assigned to or destroyed.
I most certainly agree that "valid/invalid" is far from ideal. It immediately opens up a possibility for a hair-splitting discussion about validity of uuid::nil(). From technical point of view uuid::nil() is certainly valid. For all other *practical* purposes it is not as uuid::nil() and NULL are created to be different from and in contrast with all the other "good" (valid?) objects. In my code I simply use something like foo::bad() to identify such instances.
The latter is not how the language interprets the default constructor.
I can't imagine what you mean by that.
My point was that the default constructor is part of the constructors family and, therefore, should behave consistently with the other constructors. And by "consistently" I mean predictably, across many classes. And overwhelmingly that is the initialization of "good" objects. Therefore, I'd expect the conceptual behavior of a custom Foo::Foo() to be similar to Foo(type =def_value) (which happens to be the default constructor as well) and auto-generated Foo() and all other constructors. Similarly to Stroustrup's "The C++ Progr. Lang." 10.2.3: class Date { ... Date(); // default Date: today }; Having said that I realize that approach causes a bit of a technical headache to the class developer as, say, lexical_cast does not work out of the box. Still, I'd go for it if a headache for one (the developer) makes life of many (users) easier.
Second, even if I cannot use operator[], so what? std::fstream has no default constructor. std::list has no operator[], std::vector has no push_front(). That did not stop anyone from using those classes. What the lack of those "features"
Do you really mean to imply that push_front, operator[], et. al. are not legitimate features?
Well, I most certainly did not mean to unconditionally imply that op[] et al are not legitimate. For some classes some functionality is not legitimate. Like std::list does have op[] for a reason. I think Scott's argument was that without the def. cnstr we woun't be able to use op[] with std::map<string, uuid>. My argument was that some things have some features and some others don't. That is there (or not there) for a purpose. If we, say, banish foo::foo() then is for a reason. Consequently, the functionality dependent on that foo::foo() will not be available for that same reason -- 'foo' should not be created with the def. cnstr. Did I manage to explain it better this time? Best, V.

On Tue, Dec 23, 2008 at 02:04, Vladimir Batov <batov@people.net.au> wrote:
... My argument was that some things have some features and some others don't. That is there (or not there) for a purpose. If we, say, banish foo::foo() then is for a reason. Consequently, the functionality dependent on that foo::foo() will not be available for that same reason -- 'foo' should not be created with the def. cnstr. ...
Interestingly, I think that's the contrapositive of mine: If removing the default constructor prevents something from being useful in reasonable combinations with other classes, then removing the default constructor is a bad idea.

On Tue, Dec 23, 2008 at 02:04, Vladimir Batov <batov@people.net.au> wrote:
... My argument was that some things have some features and some others don't. That is there (or not there) for a purpose. If we, say, banish foo::foo() then is for a reason. Consequently, the functionality dependent on that foo::foo() will not be available for that same reason -- 'foo' should not be created with the def. cnstr. ...
Interestingly, I think that's the contrapositive of mine: If removing the default constructor prevents something from being useful in reasonable combinations with other classes, then removing the default constructor is a bad idea.
Yes, your view has its merit... but I like mine better. :-) In fact, I do not believe anyone uses purely one approach or the other. My overwhelming working style is from inside out. That is, driven by the applicability of certain functionality to the particular class in question. Indeed, the introduction of that functionality is most often driven by some *external* need (as in your approach). However, the applicability for me is an overriding criterion. V.
participants (3)
-
David Abrahams
-
Scott McMurray
-
Vladimir Batov