通常对于我的模板化类,我在.hpp
文件中包含声明,并在.t.hpp
文件中包含模板化实现代码。我在.cpp
文件中明确地实例化了这个类:
template class MyClass< AnotherClass >;
其目标代码放在库中。
问题在于,如果我尝试使用operator<<
打印对象,.hpp
文件在.t.hpp
文件中声明并在template<class T>
std::ostream& operator<<( std::ostream& os, const MyClass<T>& c)
{
os << "Hello, I am being output.";
return os;
}
文件中定义为:
.t.hpp
我收到链接器错误,指出右边的符号未定义。
我理解这是因为这个模板化的函数在类没有显式实例化时。有没有办法绕过这个,除了在我想在类上使用operator<<
时包含.hpp
文件,或者将模板化的函数代码移动到{{1}}文件中?我可以显式实例化函数代码吗?
答案 0 :(得分:2)
您可以显式实例化功能模板
template std::ostream& operator<<(std::ostream&, const MyClass<int>&);
使用T = int
实例化专业化。如果可以推导出所有模板参数,则可以省略模板参数括号(如本例中的类型MyClass<int>
。如果不能,例如因为模板参数不在函数参数类型中出现,你必须明确指定它
template<typename T> void f() { }
template void f<int>();
答案 1 :(得分:2)
请参阅litb's solution。
对于您的具体情况,编译器可以从参数和返回类型推导出所有模板参数,但如果不能,则可以明确地给出它们:
template std::ostream& operator<< <T>(std::ostream&, const MyClass<T>&);
如果可以推导出模板参数,则仍然允许这样做。
请问:您是否有理由明确地实例化所有内容?你为自己做了很多工作。通过避免在任何地方都包含模板源代码,您肯定会节省编译时间,但在开发人员时间是否值得?