неоднозначность специализации шаблона разрыва c ++

Я перечитывал Шаблон метапрограммирования на С ++ и делать упражнения, содержащиеся в нем, и столкнулись с проблемой. Суть проблемы можно увидеть на этом небольшом примере:

    template <class A, class B>
struct C;

template <class A>
struct C<A,A>
{
typedef some_type type;
};

template <class A, class B>
struct C<A*,B>
{
typedef some_other_type type;
};

int main()
{
C<int*,int*> c;
}

Это не скомпилируется, потому что тип c неоднозначен. Компилятор не может сказать, какую специализацию предполагается создать, однако я знаю, что в таком случае я хочу вызвать первую специализацию. Решение, которое я нашел, состоит в том, чтобы переписать его так

    template <class A, class B>
struct C;

template <class A, class B>
struct C<A*,B>
{
typedef typename boost::mpl::if_c<boost::is_same<A*,B>::value,
some_type, some_other_type>::type type;
};

Проблема с этим решением заключается в том, что у меня фактически есть частичные специализации для каждого из типов указателей, констант, ссылок и массивов, поэтому мне пришлось добавить эту проверку для каждой специализации в отдельности.

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

     template <class A>
struct C<A,A>
{
typedef some_type type;
};

вместо какой-либо другой специализации в случае двусмысленности?

Для тех, кто интересуется, вопрос, над которым я работаю, это глава 1, вопрос 1

2

Решение

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

template< class A, class B, class Enable = void >
struct C;
template< class A >
struct C<A, A, void> {...};
template< class A, class B >
struct C<A*, B, typename boost::disable_if<boost::is_same<A*, B> >::type> {...};

Теперь, если вы хотите обработать константный указатель или что-то еще, вы можете расширить свое состояние в соответствии с чертами типа (is_const, is_pointer…)!

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]