编译器不创建模板的ostream <<运算
-
23-08-2019 - |
题
我有一个类,在一个头定义为:
template <typename T> class MyClass
{
template <typename U> friend std::ostream& operator<<(std::ostream& output, const MyClass<U>& p);
public:
...
}
在一个实现文件,我有:
template <typename U> std::ostream& operator<<(std::ostream& output, const MyClass<U>& m)
{
output << "Some stuff";
return output;
}
所有看上去还算清净。然而,当我尝试使用该运营商(即性病::法院<< MyClass的()),我得到下面的连接错误:
Undefined symbols: std::basic_ostream<char, std::char_traits<char> >& operator<< <InnerType>(std::basic_ostream<char, std::char_traits<char> >&, MyClass<InnerType> const&)
我惊讶的编译器没有automagicially产生这对我来说...任何建议,我在做什么错了?
解决方案
在一个实现文件,我有:
这就是问题所在。你不能分割头和实现文件之间的模板定义。由于模板的性质,C ++编译器是挑剔这里。定义所有的代码在头,使其工作。
在事实上,这里的问题是,所有模板定义必须驻留在同一个编译单元内,因为C ++标准没有定义如何信息模板跨越不同的单元是共用的。这些单元由连接器缝合在一起,但泛型是在编译时(这较早),不的链接时。
解决理论上,C ++标准定义的关键字,export
,来处理这些情况。在实践中,否编译器实现这一点(有一个例外?),并没有打算改变这一点,因为成本/效用权衡不被认为不够好。
其他提示
有太多的模板 - 此作品:
#include <iostream>
using namespace std;
template <typename T> struct MyClass {
friend ostream & operator << ( ostream & os, MyClass<T> & c ) {
os << "MyClass\n";
return os;
}
};
int main() {
MyClass <int> c;
cout << c;
}
不隶属于 StackOverflow