
On 01/15/2005 02:25 PM, David Abrahams wrote: [snip]
Maybe. The one I'm using comes from the C++ Standard:
OK. As I said below, our definitions differ.
3 Basic concepts [basic] .... 4 A name is a use of an identifier (2.10) that denotes an entity or label (6.6.4, 6.1). A variable is introduced by the declaration of an object. The variable's name denotes the object.
Besides, if an expression provides the same capability as a name, i.e. the ability to access the element, what's the importance of providing a "real name" (i.e. a c++ identifier) for the element?
None other than ease-of-use. The point of that note about names is to say you can't access an arbitrary member of that composed class by naming the member in the usual way, because all those members will have the same name, and that's unavoidable with TMP. Nothing more.
OK. I read the page differently. I thought it meant that there was difficult or impossible to access the elements. Then there's the sentence on p. 191: We can't access any other than the first one directly. OK, I guess "can't access directly" does not mean "can't access", but then consider the next paragraph: it's difficult to access the value member of a given type even by casting to an appropriate base class. This leaves me with the impression that it's "difficult" to access members other than the first; yet a template member function such as boost::tuple's, get<1>, doesn't seem difficult, at least to me.
Anyway, my definition of name differs from yours, but if the only purpose is to provide a compile-time evaluated offset from some container, then both definitions satisfy the purpose.
Not really. My definition doesn't really allow for much compile-time evaluation.
True, it's much simpler, but does involve compile-time evaluation of offset from the start of the structure.
Also, your sample code has no get_tail member template, so I don't see
^^^^^^^^^^^^^^^^^^^^^^^^
OK, the key work is *member*. I apologize. There is no member template.
how that could compile...
I've replaced the file with another, get_inherit_side_test.cpp, which, in test_instantiate(void), actually creates an instance of the tuple_type and accesses the 0-th element with: t.get_inherit_side<inherit_side_right,tuple_type,0>::type::left_type::value; Obviously, this could be shortened with a member template, t.get<0>() which simply returned the above expression. The uploaded code compiles with just a warning about t being used before it's defined.
I just downloaded it and it has get_tail specializations on lines 34 and 46.
The code in your posting used the construct
r.get_tail< .... >
I don't see how that can compile unless something is defined with a member template called "get_tail."
Sorry, I should have said: r.get_tail<...>::head_type::value; but then I would have had to provide the code like that in the newly uploaded file, and it didn't seem, at the time, necessary to demonstrate my point. [snip]
Just that the book seems to indicate there's a difficulty in accessing the elements which isn't really there, unless you define typing a long compile-time evaluated expression as difficult.
It's certainly more difficult than typing
r.foo
The book isn't making a very deep point there, but the point it does make is valid.
OK, but I, and maybe others, are interpreting the page as meaning inherit_linearly is less capable than tuple as far as accessing the elements. And with a member template, like boost's tuple, r.foo is not significantly more difficult than: r.get<foo>(); where foo is maybe an enumerator "naming" say the 2nd element in the tuple.