3

How does one share common_fn() among all specializations (for Widget<A<T> > and Widget<B<T> >, no matter what T is) in the code below?

#include <cassert>

struct Afoo {};
struct Bfoo {};

template<typename T> struct A { typedef Afoo Foo; };
template<typename T> struct B { typedef Bfoo Foo; };

template<typename Type> struct Widget
{
    Widget() {}
    typename Type::Foo common_fn() { return Type::Foo(); }
    int uncommon_fn() { return 1; }
};

template<typename T> struct Widget<A<T> >
{
    Widget() {}
    int uncommon_fn() { return 2; }
};

int main()
{
    Widget<A<char> > WidgetAChar;
    assert( WidgetAChar.common_fn() == Afoo() ); // Error
    assert( WidgetAChar.uncommon_fn() == 2 );
}

I had tried earlier to simplify the question to what I thought was its essence, but it turns out that it is necessary to ask it in the context of partial specialization and traits.

Community
  • 1
  • 1
Calaf
  • 10,113
  • 15
  • 57
  • 120

1 Answers1

1

It's a little unclear what you're aiming for, in particular whether uncommon_fn is really as simple as illustrated, or might be more.

But anyway, for the example code given, consider …

#include <cassert>
#include <typeinfo>

struct Afoo {};
struct Bfoo {};

template< class T > struct A { typedef Afoo Foo; };
template< class T > struct B { typedef Bfoo Foo; };

template< class Type >
struct UncommonResult { enum { value = 1 }; };

template< class Type >
struct UncommonResult< A< Type > > { enum { value = 2 }; };

template< class Type >
struct Widget
{
    Widget() {}
    typename Type::Foo common_fn() { return Type::Foo(); }
    int uncommon_fn() { return UncommonResult< Type >::value; }
};

int main()
{
    Widget<A<char> > WidgetAChar;
    assert( typeid( WidgetAChar.common_fn() ) == typeid( Afoo ) ); // OK
    assert( WidgetAChar.uncommon_fn() == 2 );
}

Generalizing this to handle a more general uncommon_fn shouldn't be hard.

You might also consider the inheritance trick that @iammilind showed for your previous question. It might be practically simpler. However, it adds the possibility of accessing a possibly "wrong" function implementation.

Cheers & hth.

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
  • It's quite intriguing. It appears that either full or partial specialization can be a signal that one is missing a better design, just as spotting a switch statement on types is a signal that the code is missing an inheritance hierarchy. I've tested this sort of compaction and have succeeded so far in discarding all specializations in a subset of the code. – Calaf Aug 24 '11 at 04:58
  • sorry, i don't remember the last three digits, so i can't say whether your nick is "correct" ;-) – Cheers and hth. - Alf Aug 24 '11 at 05:17