未明确引用`std :: ostream&amp; SpyOutput ::运营商LT;&LT; <double>(double const&amp;)'</double>

时间:2013-06-03 05:44:40

标签: c++ ostream

我试图拦截标准输出中的“数据”(对于这个问题,我正在使用cout)。同样对于这个问题,我正在使用double,但程序应该能够处理任何原始数据类型。当我尝试编译我的代码时,我收到此错误:

  

对`std :: ostream&amp;的未定义引用SpyOutput ::运营商LT;&LT;   (double const&amp;)'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;
}

我已经搜索了这个错误(和类似的)而没有找到可行的解决方案,请提前感谢您提供给我的任何帮助或提示! : - )

2 个答案:

答案 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<<的模板实现放入头文件