Кажется, я не могу понять, что происходит не так со следующим примером.
$ cat repro.cpp
#include <iostream>
using namespace std;
template<class T>
struct S1_t
{
template<class U>
struct inner_t_x {};
using inner_t = inner_t_x<T>;
};
struct Bogus{};
template<class T>
struct Functor1
{
void operator()()
{
cout << "Functor1 FAIL: " << __PRETTY_FUNCTION__ << endl;
}
};
template<>
struct Functor1<typename S1_t<Bogus>::template inner_t_x<Bogus>>
{
void operator()()
{
cout << "Functor1 PASS: " << __PRETTY_FUNCTION__ << endl;
}
};
template<class T>
struct Functor2
{
void operator()()
{
cout << "Functor2 FAIL: " << __PRETTY_FUNCTION__ << endl;
}
};
template<class T>
struct Functor2<typename S1_t<T>::template inner_t_x<T>>
{
void operator()()
{
cout << "Functor2 PASS: " << __PRETTY_FUNCTION__ << endl;
}
};
template<class T>
void eval()
{
Functor1<T>{}();
Functor2<T>{}();
}
int main()
{
eval<S1_t<Bogus>::inner_t>();
return 0;
}
$ clang++ repro.cpp -std=c++11 -Wall && ./a.out
Functor1 PASS: void Functor1<S1_t<Bogus>::inner_t_x<Bogus> >::operator()()
Functor2 FAIL: void Functor2<S1_t<Bogus>::inner_t_x<Bogus> >::operator()() [T = S1_t<Bogus>::inner_t_x<Bogus>]
В Functor1
я явно специализируюсь на типе Bogus
, и эта специализация действительно вызывается. Однако в Functor2
допускается вывод типа, но частичная специализация терпит неудачу, и вместо этого создается экземпляр общего шаблона. Тем не менее, __PRETTY_PRINT__
показывает одну и ту же подпись для Functor1
и Functort2
при создании экземпляра.
Может ли кто-нибудь объяснить это поведение, и есть ли способ исправить частичную специализацию Functor2
, чтобы соответствовать этому сценарию? Спасибо!
fwiw: Изменение частичной специализации Functor2
на
template<class T>
struct Functor2<typename S1_t<Bogus>::template inner_t_x<T>>
{
void operator()()
{
cout << "Functor2 PASS: " << __PRETTY_FUNCTION__ << endl;
}
};
дает правильный вывод
Functor1 PASS: void Functor1<S1_t<Bogus>::inner_t_x<Bogus> >::operator()()
Functor2 PASS: void Functor2<S1_t<Bogus>::inner_t_x<Bogus> >::operator()() [T = S1_t<Bogus>::inner_t_x<Bogus>]
но это не вариант в моем случае использования.
template<> struct Functor1
нет типа? Может быть, это просто какой-то особый синтаксис, которого я не знаю, но выглядит это странно. - person maddin45   schedule 14.12.2015