是否有人知道根据下面的规则代码不编译?
template <class T>
struct B
{
typedef T type;
};
template<class T>
struct X
{
};
template<class T>
struct X<B<T>::type*>//HERE I'M PARTIALLY SPECIALIZING (WELL, TRYING TO...)
{
};
Run Code Online (Sandbox Code Playgroud)
请参阅代码中的注释.
您认为这会如何运作?编译器会查看某个类的某个类是否有类型为typedef"type"的类?
它不会.即使它是一个指针.
请记住,大概你的B模板可能是专门的地方,所以类型并不总是T*,但它不能用逆向工程推断它.
对于那些完全不理解我的答案的人,你要求编译器做的是找到一个类U,这样B :: type就是你作为参数传入的类.
class Foo;
class Bar;
template<> struct B<Foo>
{
typedef int type;
};
template<> struct B<Bar>
{
typedef int type;
};
X<int*> // ambiguous, T is Foo or Bar?
Run Code Online (Sandbox Code Playgroud)
很难确切地知道你为什么要做你想做的事.您可以对所有指针进行部分特化,然后对特定指针进行全面的特化,这可以根据另一个模板实现.
您需要使用typename关键字作为,
template<class T>
struct X<typename B<T>::type*>
{
};
Run Code Online (Sandbox Code Playgroud)
这是因为B<T>::type是一个从属名称。所以typename是必须的!
——
编辑:
即使在 put 之后typename,它也不会编译。我想这是因为类型的扣T在B<T>从X<U>难,或者可能不可能的,因为编译器。所以我相信它的非演绎上下文。
请参阅此处的类似示例和讨论:
但是,如果您将专业化更改为:
template<class T>
struct X<B<T> >
{
};
Run Code Online (Sandbox Code Playgroud)
然后它成为可推论的上下文,因此将编译。