我试图拦截标准输出中的“数据”(对于这个问题,我正在使用cout)。同样对于这个问题,我正在使用double,但程序应该能够处理任何原始数据类型。当我尝试编译我的代码时,我收到此错误:
对`std :: ostream&的未定义引用SpyOutput ::运营商LT;< (double const&)'collect2:error:ld返回1退出状态
这是我的主要内容:
#include "SpyOutput.h"
#define endl '\n'
int main ( int argc, char *argv[], char *env[] ) {
double d1 = 12.3;
SpyOutput spy(&cout);
spy << d1;
return 0;
}
这是我的头文件:
#include <iostream>
using namespace std;
class SpyOutput {
private:
ostream* output;
public:
SpyOutput(ostream* os);
template <class T>
ostream &operator<<(const T &x);
};
这是我的实施文件:
#include "SpyOutput.h"
SpyOutput::SpyOutput(ostream* os){
output = os;
}
template <class T>
ostream& SpyOutput::operator<<(const T &x){
// SOME CODE GO HERE
return *output;
}
我已经搜索了这个错误(和类似的)而没有找到可行的解决方案,请提前感谢您提供给我的任何帮助或提示! : - )
答案 0 :(得分:2)
有关无法编译的解释,请参阅"Why can't I separate the definition of my templates class from its declaration and put it inside a .cpp file?"
作为示例,请考虑头文件foo.h,其中包含以下模板函数声明:
// File "foo.h"
template<typename T>
void foo();
现在假设文件foo.cpp实际定义了该模板函数:
// File "foo.cpp"
#include <iostream>
#include "foo.h"
template<typename T>
void foo()
{
std::cout << "Here I am!\n";
}
假设文件main.cpp通过调用foo():
来使用此模板函数// File "main.cpp"
#include "foo.h"
int main() { foo<int>(); ... }
如果编译并链接这两个.cpp文件,大多数编译器都会生成链接器错误。因为为了让编译器生成代码,它必须看到两者模板定义(不仅仅是声明)和特定类型/用于“填写”模板的任何内容。如果模板体在.cpp中定义,编译器将不会看到它,因此不会为它生成任何代码。
围绕此问题有多种可能的解决方案。我建议将模板函数的定义移到.h文件中。
// File "foo.h"
template<typename T>
void foo()
{
std::cout << "Here I am!\n";
}
在您的来源中,您可以照常调用它:
// File "main.cpp"
#include "foo.h"
int main() { foo<int>(); ... }
答案 1 :(得分:1)
您需要将SpyOutput::operator<<
的模板实现放入头文件