C++ 模板结构内部模板结构的模板专业化失败
我似乎不知道下面的例子出了什么问题C++ 模板结构内部模板结构的模板专业化失败,c++,templates,c++11,partial-specialization,C++,Templates,C++11,Partial Specialization,我似乎不知道下面的例子出了什么问题 $ 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>
$ 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 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>]
Functor1过程:无效Functor1::operator()()
Functor2过程:无效Functor2::运算符()[T=S1\u T::inner\u T\u x]
但在我的用例中,这不是选项。类型名称S1\t::…
在部分专门化中是不可推断的
使用internal\u t
而不是internal\u t\u x
时,出现了一个更清楚的错误:
main.cpp:41:8:错误:部分专门化中无法推断模板参数:
结构函子2
^
main.cpp:41:8:注:“T”
main.cpp:41:8:警告:类模板部分专门化包含无法推导的模板参数;这种局部专门化永远不会被使用
永远不会使用函数2
的专门化。编译器可能会发出警告,但在您的情况下不会。它不可推断的原因很简单:想象你后来添加了
struct Hogus;
template<>
struct S1_t<Hogus>
{
template <typename U>
using inner_t_x = S1_t<Bogus>::inner_t_x<Bogus>;
};
struct Hogus;
模板
结构S1\u t
{
模板
使用internal\u t\u x=S1\u t::internal\u t\u x;
};
然后
S1_t::internal_t_x
和S1_t::internal_t_x
将是相同的类型。因此,Functor2
的部分特化中的模板推导可以产生T=Bogus
或T=Hogus
。因此,在任何情况下都无法明确推断 为什么模板结构Functor1
中没有类型?也许这只是一些我不知道的特殊语法,但它看起来很奇怪。引用(相对于n4567):[temp.decrete.type]p5和p6“当以包含非推断上下文的方式指定类型名时,构成该类型名的所有类型也都是非推断的。”换句话说,绝对没有办法推导出T,对吗?如果是这样的话,我会被缺乏编译器警告的想法误导,认为类型推断是在::inner_t_x上完成的。感谢一个生动的例子,它突然变得非常清楚。那么,有什么方法可以毫不含糊地推导出T型呢?我的直觉是没有,但我不是100%确定。我不认为有任何方法可以推断嵌套类型的外部和内部。很抱歉
main.cpp:41:8: error: template parameters not deducible in partial specialization:
struct Functor2<typename S1_t<T>::inner_t>
^
main.cpp:41:8: note: 'T'
main.cpp:41:8: warning: class template partial specialization contains a template parameter that cannot be deduced; this partial specialization will never be used
struct Hogus;
template<>
struct S1_t<Hogus>
{
template <typename U>
using inner_t_x = S1_t<Bogus>::inner_t_x<Bogus>;
};