1

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

未定义对 `std::ostream& SpyOutput::operator<< (double const&)' collect2 的引用:错误: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;
}

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

4

2 回答 2

2

有什么问题?

有关它无法编译的解释,请参阅“为什么我不能将模板类的定义与其声明分开并将其放入 .cpp 文件中?”

例如,考虑包含以下模板函数声明的头文件 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>();   ... }
于 2013-06-03T07:12:19.130 回答
1

您需要将模板实现SpyOutput::operator<<放入头文件中

于 2013-06-03T05:46:06.563 回答