* Bo Yang:
Hi ,
I am reading some boost code now , and
I got confused by the following code in the
add_reference type trait .
template <class T> T&(* is_reference_helper1(wrap<T>) )(wrap<T>);
Yes, that /is/ confusing.
The main problem is perhaps to determine the "innermost" thing declared,
but as the famous Norwegian TV-cook Ingrid Espelid used to say, "but we
have cheated and ... voilà!", and out of the oven she lifted a perfect
.... something ... ; in this case, out of the oven comes the name
is_reference_helper1 (am I mixing metaphors?).
Looking at both sides of that name, the "function call" argument list to
the right takes precedence, it's done first, so to speak (although
nothing is done, but you can read a declaration in much the same way as
it would have been executed as an expression, from inner to outer).
So, hypothetically doing that hypothetical function call, we find that
is_reference_helper1 must be a function taking a wrap<T> argument, by value.
Now for the result type, you need to work your way outwards in the
declaration.
And the first thing encountered then is the * on the left.
As an expression that would mean a dereferencing of a pointer, and so in
a declaration it means the thing declared /is/ a pointer (otherwise it
couldn't be dereferenced). So the hypothetical function call yields a
pointer. And so is_reference_helper1 is a function returning a pointer.
But a pointer to what?
Going still farther outwards in the declaration, we have on the left
'T&' and on the right '(wrap<T>)'. Again, if this were an expression
the thing on the right would be a function call's argument list, and
taking precedence. So we now know that the pointer is a pointer to a
function, let's call it ResultFunc, that takes a wrap<T> argument by value.
Finally, the result type of ResultFunc is 'T&', a reference to an object
of type T.
So is_reference_helper1 is a function that takes a wrap<T> argument by
value, and returns a pointer to a function (the ResultFunc) that takes a
wrap<T> argument by value and returns a reference to a T object.
Incidentally, Google code search, applied to 'is_reference_helper1', in
addition to finding that line in the Boost library, turned up this
description from the MSVC port of Andrei Alexandrescu's Loki Library:
"is_reference_helper1 is a function taking a Type2Type<T> returning a
pointer to a function taking a Type2Type<T> returning a T&", which
char is_reference_helper1(...);
template <class T> no_type is_reference_helper2(T&(*)(wrap<T>));
yes_type is_reference_helper2(...);
template <typename T>
struct is_reference_impl
{
BOOST_STATIC_CONSTANT(
bool, value = sizeof(
::boost::detail::is_reference_helper2(
::boost::detail::is_reference_helper1
:boost::type_traits::wrap<T>())))
== 1
);
};
Why does function is_reference_helper1 define in such
a way , I can't understand what is it !
That's because Real Programmers can't be bothered with using 'typedef',
or generally, naming things. After all, if the code could be understood
by others, then one might soon be replaced by someone else. Okay,
that's unfair, especially to Andrei who (it seems) bothered to write the
clear explanatory comment; an equally probable explanation is that in
the heat of the hunt, make that thing work, one has to try out many
different things, and the less typing per thing tried the better, and
then the first thing that works becomes embedded in stone, even if
unreadable, because one is already moving on to the next problem...
Could someone explain these code for me ?
See above.
You're welcome.
Cheers,
- Alf