
on Sun Dec 28 2008, Howard Hinnant <hinnant-AT-twcny.rr.com> wrote:
I.e. The namespace of A is associated with std::vector<T, A>, whether or not vector derives from A. Silly me for forgetting that. /Some/ day I may master C++...
Oh, me too, I forgot that.
And, BTW, this is all way too hard; at its limit it leads to building every generic class template out of tuples instead of ordinary members.
This conclusion would be an option for class template designers, not a requirement. And it would be easier than constantly reinventing EMO.
Yes, but, why should we have to worry about that?
Back when c++std-lib-18989 was written (about 18 months ago) I implemented such a tuple, and used that implementation in preparing my previous message demonstrating a space-optimizing tuple. You are quite correct that the tuple does indeed end up deriving (indirectly in my example implementation) from client-supplied empty members. I think perhaps one important caveat is that the tuple *does not* derive from client-supplied types which have virtual functions (at least no known implementation of polymorphic types qualify as "empty"). Said differently, this implementation of tuple only derives from empty class types, and not from non-empty class types.
Understood.
Because of this caveat, and because of the associated namespace rule involving template parameters of template class types, I have not yet come up with a way for clients to detect the size optimization with the following exceptions (which I hope are acceptable to clients):
1. The tuple size optimization can be detected with sizeof. 2. The tuple size optimization can be detected by comparing the addresses of empty members and seeing that they may not be unique with respect to other tuple members:
Hmm, int f(void*); char* f(some_empty_type*); int x = f(tuple_containing_some_empty_type); // compilation error.
#include <tuple> #include <cstdio>
struct empty1 {}; struct empty2 {};
int main() { typedef std::tuple<empty1, empty2> T2; T2 t; std::printf("address of std::get<0>(t) is %p\n", &std::get<0>(t)); std::printf("address of std::get<1>(t) is %p\n", &std::get<1>(t)); }
address of std::get<0>(t) is 0xbffff65f address of std::get<1>(t) is 0xbffff65f
"Unacceptable" means of detecting this optimization would include a change in overload resolution due to associated namespaces depending on whether or not the space optimization was performed (which would likely be error prone).
It's not just a matter of what namespaces are associated, but also which functions in those namespaces will match.
We probably should have an EMO in the core language after all.
I would probably be in favor of such a core change. Indeed, in the "next language" I imagine that a tuple-like construct might be a built- in type which lays the foundation for the layout of every client- defined aggregate type (complete with built-in type and value introspection). Imagine if you could inspect the member types of a struct as easily as you can a std::tuple. :-)
Yup. -- Dave Abrahams BoostPro Computing http://www.boostpro.com