我可以在类声明中使用部分模板专业化
template<class T1, class T2>
struct A
{
void foo() { cout << "general"; }
};
template<class T1>
struct A<T1, int>
{
void foo() { cout << "partial specialization"; }
};
但是当我试图在课堂宣言之外做这件事时
template<class T1, class T2>
struct A
{
void foo();
};
template<class T1, class T2>
void A<T1, T2>::foo() { cout << "general"; }
template<class T1>
void A<T1, int>::foo() { cout << "partial specialization"; }
我收到以下错误:
无效使用不完整类型«struct A&lt; T1,int&gt;»
当您想要重新定义所有成员时,使用第一种方法不是问题,但如果您只想重新定义一种没有代码重复的方法,那该怎么办?
那么,是否可以在类定义之外使用部分模板特化?
答案 0 :(得分:3)
在你失败的例子中:
template<class T1>
void A<T1, int>::foo() { cout << "partial specialization"; }
您指的是尚未定义的A的特化(您在第二个示例中仅定义了完整模板)。
如果在引用它之前添加特化,它确实可以工作:
template <class T1>
struct A<T1, int>
{
void foo ();
};
template <class T1>
void A<T1, int>::foo ()
{
/* something */
};
答案 1 :(得分:2)
c ++标准禁止专门使用没有完全专门化外部模板的方法。所以是的,这是不可能的。我不确定它是否对c ++ 11有效,但我怀疑它是。
解决此问题的一种方法是像第一个示例中那样专门化外部模板。
顺便说一下,这可能是另一种解决方法:
template<class T1, class T2>
struct A
{
template<unsigned int I>
void foo() { cout << "general"; }
template<>
void foo<2> () { cout << "specialization"; }
};
这是有效的,因为这不是专业化,而是方法的不同模板。
答案 2 :(得分:2)
当您想要重新定义所有成员时,使用第一种方法不是问题,但如果您只想重新定义一种没有代码重复的方法,那该怎么办?
这是可以使用特征技术的地方。见http://www.boost.org/community/generic_programming.html#traits
一些用法:
template <class T1, class T2>
struct ATraits {
static void foo() {}
};
template <class T1>
struct ATraits<T1,int> {
static void foo() {}
};
template <class T1, class T2>
struct A {
void foo() { ATraits<T1,T2>::foo(); }
};
答案 3 :(得分:0)
这里讨论相同的主题: "invalid use of incomplete type" error with partial template specialization
+1 tozka的解决方案,如果A除了foo()之外不需要知道我,这是一个很好的解决方法。否则,请查看上述问题的答案。