template <class T>
class Test
{
public:
template<class U> void f(); //generic function
template<> void f<char>(); //Specialization for char.
};
template <class T>
template<class U>
void Test<T>::f() //Definition of generic function
{
}
template<>
template<> void Test<char>::f<char>(){} //Definition of specialization.
int main()
{
Test<char> ob1;
ob1.f<char>(); //Works fine.
Test<int> ob2;
ob2.f<char>(); //Produces linker error.
}
链接器错误
error LNK2019: unresolved external symbol "public: void __thiscall
Test<int>::f<char>(void)"
我的要求是:我应该能够将任何类型传递给Test类,并将任何类型传递给函数f()。我应该可以使用下面所有类型的组合。
Test f() -------------- int char char int int int
我可以通过定义下面的另一个函数来解决错误。
template<>
template<> void Test<int>::f<char>(){}
但是,将Test类作为模板的用途是什么?如何让它适用于所有组合?
答案 0 :(得分:5)
C ++ 03,§14.7.3/ 2:
应在名称空间中声明显式特化 template是成员,或者,对于成员模板,在其名称空间中 封闭类或封闭类模板是成员。 成员函数,成员类或静态数据的显式特化 类模板的成员应在其名称空间中声明 类模板是成员。
因此,您应该在类之外声明您的专业化,例如:
template <class T>
class Test
{
public:
template<class U> void f(); //generic function
};
template <class T>
template <class U>
void Test<T>::f() {} //Definition of generic function
template<>
template<>
void Test<char>::f<char>(){} //Specialization.
int main()
{
Test<char> ob1;
ob1.f<char>();
Test<int> ob2;
ob2.f<char>();
}
答案 1 :(得分:3)
您遇到的问题是您已在f
模板中声明了char
Test
的专业化,这是不正确的。编译器没有检测到错误,但是在所有模板实例化中,您希望为f
char
提供template <typename T>
struct Test {
template <typename U> void f();
template <> void f<char>(); // <- Incorrect
};
的特化,这让您感到困惑和解释:
Test<int>
当您编写f
时,编译器会实例化模板,并且(错误地)接受该模板并解释char
中Test<int>
的{{1}}的专门化。< / p>
删除该行,您将获得要编译的代码。它将仅对Test<char>::f<char>()
使用专门化,我不确定这是否是您想要的。
如果您打算f
char
使用所有实例化类型进行专门化,则不允许这样做。定义模板特化时,所有封闭模板都是专用的。常见的解决方法不是提供专业化,而是提供成员函数的不同重载:
template <typename T>
struct Test {
template <typename U> void f( U );
void f( char );
};
但是那对你没有多大帮助,因为你不能为相同的参数提供不同的重载(在你的情况下没有参数)。此外,在您的情况下,您必须显式调用模板进行区分,并且明确请求模板的代码不会获取重载:
int main() {
Test<int> t;
t.f<char>(); // will call template, not "void f(char)"!!
}
如果没有关于你真正想要达到的目标的更多细节,我无法考虑其他可能解决问题的方法。
答案 2 :(得分:0)
我的要求是:我应该能够将任何类型传递给Test类,并将任何类型传递给函数f()。我应该可以使用下面所有类型的组合。
为什么需要明确的专业化?你为什么不必要地想让你的代码变得复杂?
以下适用于您列出的所有组合。
template <class T>
class Test
{
public:
template<class U> void f();
};
template <class T>
template<class U>
void Test<T>::f(){}
int main()
{
Test<char> ob1;
ob1.f<char>(); //Works fine. T = char, U = char
Test<int> ob2;
ob2.f<char>(); //Works fine T = int, U = char
}