
On Jul 21, 2006, at 4:14 PM, David Bergman wrote:
What about the use of endian objects where one would expect raw integral objects? Such use includes
template<typename DestT, typename SourceT> DestT make_double(SourceT val) { return 2 * val; }
big4_t doubleVal = make_double<big4_t>(21);
This doesn't seem to be a common use case for binary data structures used in I/O.
The generic code need not even deal with arithmetic at all, such as in
vector<int> int_vect; ... vector<big4_t> big4_vect(int_vect.begin(), int_vect.end());
And this has a workaround by using a for loop.
Since we do not have the luxury of two user-defined conversions in the chain from 'int' to 'endian<...>', which would allow us to write an intermediate type with both an 'int' constructor and an 'endian' operator, we have to choose: unions (and other pure POD scenarios) or conversion from raw integral objects. I think a wise decision was made in the choosing the latter.
I guess I disagree. With an assignment operator, most of the conversions from raw integral types are covered, and you can still use 'em in unions. If you still feel this way, would it be at least possible to add a #define to disable the constructors? This would allow the user of the library to choose what is important to them, rather than the library writer. We obviously can't support all use cases with the current limitations of the C++ language.
What good is a single big-endian variable on the stack? I see far more use cases for these classes in structs and unions, and then writing them out a file descriptor.
But we also want it to be interchangeable - as far as possible - with integers in generic code (whether templates or "copy-and-pasting".)
Yes, I would agree. As far as possible, but not at the expense of legitimate and useful use cases. An endian class library, that could be used in unions, would have saved me a good chunk of time on a recent client project. I keep re-reading the documentation, and nowhere does it explain that interchangeability with integer types is a key requirement. It talks about providing "integer-like byte-holder binary types with explicit control over byte order, value type, size, and alignment." It talks about "use cases almost always involve I/O, either via files or network connections." Unions are not uncommon in these situations. In fact, the example at the end gives a structure representing a file format. Again, it is not at all uncommon to have structures that represent file formats that require unions. Even one of the FAQ questions talks about why operators are are provided at all, since that isn't really the prime feature of these classes. Basically, they are nice to have to make code more readable. And I agree with that, so long as reducing clutter doesn't inhibit some real-world use cases. Removing constructors makes only a small fraction of uses cases more wordy. Well, if I haven't convinced you by this point, hopefully at you'll at least consider using a #define to disable constructors for those people that *do* find a real-world use for such classes in unions. -Dave