У меня есть следующий код:Неоднозначность частичная специализация в зависимости от станд :: enable_if
#include <iostream>
template <class T, typename U = void> class A;
template <class T>
class C
{
public:
typedef T Var_t;
};
template <class T>
class B : public C<T>
{
};
template <class T>
class A<B<T>>
{
public:
A() { std::cout << "Here." << std::endl; }
};
template <class T>
class A<T, typename std::enable_if<
std::is_base_of<C<typename T::Var_t>, T>::value>
::type>
{
public:
A() { std::cout << "There." << std::endl;}
};
int main()
{
A<B<int>> a;
return 0;
}
Когда компилятор пытается создать экземпляр второй частичной специализации с параметром B<int>
, std::is_base_of<C<int>, B<int>>::value
является true
, и поэтому std::enable_if<...>::type
возвращается void
(тип по умолчанию, если он не указан). Это вызывает ошибку «неоднозначной частичной специализации», поскольку компилятор не может решить между первой и второй частичными специализациями. Все идет нормально. Однако, когда я заменяю код в std::enable_if
, просто должен быть true
(то есть вторая частичная специализация равна template <class T> class A<T, typename std::enable_if<true>::type>
), код компилируется и запускается. Он выводит "Here"
, указав первую специализацию.
Мой вопрос: если вы оба оцените до void
, в конце концов, почему поведение std::enable_if<true>::type
отличается от std::enable_if<std::is_base_of<...>::value>::type
?
Это поведение было протестировано и проверено на Ideone here.
Итак, вы говорите, что тот факт, что у меня есть специализация на 'T', делает компилятор« A > »и 'A>' быть одинаково специализированным? Это немного противоречит интуиции (я все еще ожидал бы, что 'A >' будет более специализированным, каким-то образом), но это имеет смысл. –
Я согласен, что на первый взгляд кажется немного контр-интуитивным, но я думаю, что, возможно, это мы читаем больше в коде, чем должны? Мы видим 'B' и думаем «весь класс, построенный вокруг' T', который должен быть более важным, чем некоторый тип, возвращаемый 'std :: enable_if'. Но в тесте enable также используется' B '. считается менее значительным, чем другое использование? –