I have a program in which I would like to use the same class name
for multiple variants, which all have different template argument lists.
Abstract example; consider these two class template signatures:
widget<typename T1, typename T2, T2 &T1::PMEMB, bool FLAG>
widget<typename T1, bool FLAG>
I don't want to make up two different names like, widget_complex and
widget_simple. The choice of which widget class should be deduced by the
parameters supplied by the user. E.g. if the user constructs like
this:
widget<foo, bar, &foo::member, true> w;
he gets the former class. If he writes this, he gets the latter:
widget<foo, false> w;
Templates already have default arguments, which is a subset
of overloading: overloading among parameter lists of different
length which share a common prefix.
I can have a two argument widget and a four-argument widget,
if two arguments are defaulted. But the first two have
to be common, so that doesn't apply here.
Specialization doesn't help either because all it does is
allow custom template expansion of the same class for
specific choices of template argument values.
--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std...@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
There is partial template specialization, which allows some kind of
overloading, with which you can even use SFINAE.
With default template parameters, you can also lay the ground to
overload on arity.
> Abstract example; consider these two class template signatures:
>
> widget<typename T1, typename T2, T2 &T1::PMEMB, bool FLAG>
>
> widget<typename T1, bool FLAG>
You can't do that. Pseudo-overloading doesn't work well if you mix
type parameters with other kinds of parameters.
You could, however, do:
widget<typename T1, typename T2, typename T3, typename T4>
widget<typename T1, typename T2>
Simply by defaulting T3 and T4 to some special void value.
>
> I don't want to make up two different names like, widget_complex and
> widget_simple. The choice of which widget class should be deduced by the
> parameters supplied by the user. E.g. if the user constructs like
> this:
>
> widget<foo, bar, &foo::member, true> w;
you'd have to do
widget<foo, bar, member<&foo::member>, true_> w;
>
> he gets the former class. If he writes this, he gets the latter:
>
> widget<foo, false> w;
widget<foo, false_> w
Not that I know.
>
> I have a program in which I would like to use the same class name
> for multiple variants, which all have different template argument lists.
>
> Abstract example; consider these two class template signatures:
>
> widget<typename T1, typename T2, T2 &T1::PMEMB, bool FLAG>
>
> widget<typename T1, bool FLAG>
In your particular case, you can wrap the constants in types and do
specialization using this, i.e. if you convert the primary template to
template <typename T1, typename T2, typename T3 = detail::unused,
typename T4 = detail::unused> class widget;
you then have instantiations like this:
widget<foo, bar, memptr<foo, &foo::member>, true_type>
and
widget<foo, true_type>
which you can distinguish by specializing. The obvious downside of
this is the ugly memptr template.