Предотвращение дублирования определений функций в частичных шаблонных специализациях при использовании признаков - PullRequest
3 голосов
/ 19 августа 2011

Как один разделяет common_fn () среди всех специализаций (для Widget<A<T> > и Widget<B<T> >, независимо от того, что такое T) в приведенном ниже коде?

#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 );
}

Я пытался ранее упростить вопрос до того, что я считал его сущностью, но оказывается, что его необходимо задать в контексте частичной специализации и черт характера.

1 Ответ

1 голос
/ 19 августа 2011

Немного неясно, к чему вы стремитесь, в частности, действительно ли uncommon_fn так же просто, как показано, или может быть больше.

Но в любом случае, для приведенного примера кода рассмотрим & hellip;

#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 );
}

Обобщение этого для обработки более общего uncommon_fn не должно быть сложным.

Вы также можете рассмотреть уловку наследования, которую @iammilind показал для вашего предыдущего вопроса. Это может быть практически проще. Однако это добавляет возможность доступа к возможно «неправильной» реализации функции.

Приветствия и hth.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...