4

Possible Duplicate:
“invalid use of incomplete type” error with partial template specialization成员函数的偏特

为什么我能做到这一点:

template <typename T> 
struct A 
{ 
    void foo(int); 
}; 

template <> 
void A<int>::foo(int) 
{ 
} 

但不是这样的:

template <typename> struct C {}; 

template <typename T> 
struct A 
{ 
    void foo(int); 
}; 

template <typename T> 
void A<C<T> >::foo(int) 
{ 
} 

对于第二种情况,GCC提供了以下错误:

test.cpp:10:23: error: invalid use of incomplete type 'struct A<C<T> >' 
test.cpp:4:8: error: declaration of 'struct A<C<T> >' 

编辑

当解释为什么第二个例子是不允许的,也请考虑使成员函数也是一个模板有没有效果上示例工作,哪些不是。也就是说,这仍然有效:

template <typename T> 
struct A 
{ 
    template <typename U> 
    void foo(U); 
}; 

template <> 
template <typename U> 
void A<int>::foo(U) 
{ 
} 

但这并不:

template <typename> struct C {}; 

template <typename T> 
struct A 
{ 
    template <typename U> 
    void foo(U); 
}; 

template <typename T> 
template <typename U> 
void A<C<T> >::foo(U) 
{ 
} 

这样的理由不能是函数模板只能是完全专用的,因为第三个例子是不是一个完整的专业化(模板参数U仍然存在),但它的工作原理。

+0

@Mankarse似乎是一个不同的问题。 –

回答

6

功能模板只能完全专用,而不能部分。

您正在使用类模板的成员函数本身是函数模板的事实,所以此规则仍然适用。


至于你的编辑:下面的东西都可以明确地(即完全)专业,从14.7.3/1:

An explicit specialization of any of the following:

— function template

— class template

member function of a class template

— static data member of a class template

— member class of a class template

— member enumeration of a class template

— member class template of a class or class template

member function template of a class or class template

can be declared by a declaration introduced by template<>;

我强调的是适用于您的情况下,这两种说法。在没有任何其他明确规定的情况下,这些实体可以部分专用而不是

+0

我不确定我是否买这个解释。假设我使用模板参数'U'将成员函数本身作为模板。那么我仍然可以定义'A :: foo(U)',但不能'A > :: foo(U)'。然而,第一个很难被认为是完全专业化的,因为它有一个模板参数('U')。 – HighCommander4

+0

@ HighCommander4:我说“成员函数”,而不是“成员模板”。如果你改变了这个问题,我改变了答案:-) –

+0

完成,请看我的编辑:) – HighCommander4