Boost logo

Boost :

From: Eric Friedman (ebf_at_[hidden])
Date: 2003-11-11 23:09:54

David Abrahams wrote:

> Eric Friedman <ebf_at_[hidden]> writes:
>>>At some point users need to learn to deal with the metafunction
>>>idiom or we're going to be adding make_ to the beginning of every
>>>metafunction name.
>>I think there is an important difference between classes that are true
>>metafunctions vs. those that are metafunctions only because of a lack
>>of template typedefs.
> Hmm: boost::type_with_alignment<N>::type

FYI, Boost.Optional didn't get the following fix until CVS revision 1.8:

   "Fixed alignment bug (::type missing)"

Though it may have been simple oversight that led to this mistake, my
guess instead is that type_with_alignment's name is to blame. I doubt
the mistake would have been made if the template were called
make_type_with_alignment (or similar).

My belief is that good metafunction names tend to be verbs, or in some
cases adjectives. In general, I find that nouns increase the potential
for confusion and misuse, even by competent programmers well-accustomed
to the metafunction idiom.

>>That is, even if C++ today had template typedefs, I believe true
>>metafunctions would not use the feature.
>>[For instance, consider type traits and MPL algorithms. If these were
>>template typedefs, then instantiation would occur immediately. This
>>would prevent many good things, such as lambda expressions, etc. So
>>even with the advent of template typedefs, I would hope true
>>metafunctions would not use them.]
>>On the other hand, if C++ had template typedefs, I would not want
>>anyone to have to write:
>> void f() {
>> recursive_variant< ... >::type v;
>> ...
>> }
> Why is lazy instantiation less useful for recursive_variant than for
> other metafunctions?

Because I believe recursive_variant purpose is not as a metafunction; it
is intended as syntactic sugar. As I've said before, ideally it would
simply be an alias (i.e. typedef) for a certain type of variant<...>.

>>That recursive_variant is a metafunction is an implementation
>>detail. Thus, it is a mistake, IMO, to expose this implementation
>>detail to the user simply because of a deficiency in C++.
>>In contrast, a name like 'make_recursive_variant' explicitly indicates
>>a metafunction. Invoking this metafunction via ::type is no longer an
>>implementation detail but rather integral to the metafunction idiom.
> I understand your point.
> recursive_variant_type<sequence>::type
> ??

Doesn't it seem confusing that 'recursive_variant_type' would in fact
*not be* a recursive variant type, but rather a metafunction for making one?

I'd like to stress that I'm not convinced that 'make_recursive_variant'
is the best name, primarily because (as you noted) the make_ prefix is
generally reserved for runtime functions.

However, let me note that misuse resulting from this confusion will look
like something like this:

   void f() {
     variant<...> v( make_recursive_variant(...) );

This will be caught immediately by the compiler with an error like "use
of class template requires template argument list." Note how *class
template* is explicitly mentioned in the error, in this case from VC7.1.

Contrast this with misuse resulting from confusion as to whether
recursive_variant_type is a metafunction:

   void f() {
     recursive_variant_type<...> v(...);

This, too, will be caught, but the error will most likely be something
like "cannot convert from 'U' to 'recursive_variant_type<T0,T1>'."

To an unfamiliar user, I imagine neither code snippet above appears
"obviously" incorrect. What I do think is obvious, though, is which
error message is more informative. In my opinion, this is enough reason
to go with a verb phrase instead of a noun.

Therefore, I plan to leave the names as make_recursive_variant, etc.
unless someone proposes another verb phrase that is better.


Boost list run by bdawes at, gregod at, cpdaniel at, john at