
On Jul 20, 2006, at 10:34 AM, me22 wrote:
I'm not a fan of that macro hackery, however...
Neither am I. :) I do feel a bit dirty for doing that, and wouldn't recommend it, if you can avoid it. But it's a system header than I cannot change. I will probably end up copying it to my project, renaming it to avoid a conflict, and do a search/replace, actually.
The problem is that the classes can't properly act "like ints". The way they are now they can't be used in a union, as you've mentions.
I totally agree that they should act as much like ints as possible.
But take out the constructors and then the following rather logical program doesn't work any more: #include
#include <iostream> int main() { boost::integer::big4_t x = 42; std::cout << x << "\n"; }
True, but a workaround is to do it in two steps: boost::integer::big4_t x; x = 42;
And it can no longer be initialised in member initializer lists. I don't know whether this or unions is a more pressing concern, however.
At least initialization has a workaround by doing it in two steps. There is no work around to allow them in unions. One argument for favoring unions over initialization is that a prime requirement of the endian types are they "must be suitable for I/O - in other words, must be memcpyable." Hence, they are designed to be used in structs and and then used directly with I/O, i.e. it's great for file formats. I doubt HFS+ is alone in using unions for file formats. I can see other uses cases for unions, too. It would be a shame if it were not possible to model these.
Do SFINAE-awayed constructors prevent a class from being used in unions? That might be a way to allow both if an eventual review can't come to a conclusion.
"SFINAE-awayed constructors" is a new term for me. After a bit of Google work, I'm still not sure I understand SFINAE enough to know what it can do, and if could help here. But as far as I know, *any* constructor prevents a class from being used in a union. One possible solution is to use add static init() methods to the template: static endian init(T i) { endian e; e = i; return e; } Then, you could initialize it like: boost::integer::big4_t x = boost::integer::big4_t::init(43); Not perfect, but less ugly then using two steps, especially, if you ignore the namespaces: big_t x = big_t::init(43); -Dave