я не могу показаться, чтобы обернуть мою голову вокруг того, что происходит неправильно в следующем примереШаблон провал специализации для шаблонного структуры внутри шаблонного структуры
$ 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'? Может быть, это просто какой-то специальный синтаксис, который я не знаю, но выглядит странно. – maddin45