undefined reference to `std::ostream& SpyOutput::operator<< <double>(double const&)'

StackOverflow https://stackoverflow.com/questions/16890633

  •  30-05-2022
  •  | 
  •  

Question

I'm trying to intercept "the data" from standard output (for this question I'm working with cout). Also for this question I'm working with double, but the program should be able to handle any primitive data type. When I try to compile my code I get this error:

undefined reference to `std::ostream& SpyOutput::operator<< (double const&)' collect2: error: ld returned 1 exit status

this is my main:

    #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;
    }

this is my header file:

#include <iostream>
using namespace std;

class SpyOutput {
private:
ostream* output;

public:
SpyOutput(ostream* os);
template <class T>
ostream &operator<<(const T &x);
};

this is my implementation file:

#include "SpyOutput.h"
SpyOutput::SpyOutput(ostream* os){
output = os;
}

template <class T>
ostream& SpyOutput::operator<<(const T &x){
// SOME CODE GO HERE
return *output;
}

I have googled this error (and similar) without finding a working solution, thanks in advance for any help or hint that you can provide to me! :-)

Was it helpful?

Solution

What's the problem?

For an explanation why it doesn't compile, see "Why can't I separate the definition of my templates class from its declaration and put it inside a .cpp file?"

As an example, consider the header file foo.h which contains the following template function declaration:

// File "foo.h"
template<typename T>
void foo();

Now suppose file foo.cpp actually defines that template function:

// File "foo.cpp"
#include <iostream>
#include "foo.h"

template<typename T>
void foo()
{
  std::cout << "Here I am!\n";
}

Suppose file main.cpp uses this template function by calling foo():

// File "main.cpp"
#include "foo.h"

int main() {   foo<int>();   ... }

If you compile and link these two .cpp files, most compilers will generate linker errors. Because in order for the compiler to generate the code, it must see both the template definition (not just declaration) and the specific types/whatever used to "fill in" the template. If the template body is defined in the .cpp the compiler won't see it and hence won't generate any code for it.

How to fix it?

There is more than one possible solution around this issue. I suggest moving the definition of the template function into the .h file.

// File "foo.h"
template<typename T>
void foo()
{
  std::cout << "Here I am!\n";
}

In your source you can call it as usual:

// File "main.cpp"
#include "foo.h"

int main() {   foo<int>();   ... }

OTHER TIPS

You need to place your template implementation of SpyOutput::operator<< into the header file

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top