-1

Declaration inside bmd2fileio.h

class bmd2File {
  public:
    template <typename T>
    void write(const T & t) const throw (bmd2Exception);

Definition inside bmd2fileio.cpp

#include "bmd2fileio.h"

...

template <typename T>
void bmd2File::write(const T & t) const throw (bmd2Exception)
{
  #ifdef _WIN32

    LPDWORD lpNumberOfBytesWritten;
    bool written = WriteFile(this->handle,
                              t,
                              sizeof(T),
                              lpNumberOfBytesWritten,
                              0);

    if (!written)
    {
      printf("Not written.");
    } else {
      printf("Written.");
    }

  #else

  #endif

}

The (failed) call inside main.cpp:

#include "bmd2fileio.h"

...

const std::string data = "meow";

std::auto_ptr<bmd2File> myBmdFile(new bmd2File(fileName));

myBmdFile->write(data);

It won't link with the following error:

undefined reference to `bmd2File::write(std::string const&) const'

I thought that would resolve to std::string such that the linker would find my function just fine... but not the case. Doh!

Sharp Steel Software
  • 4,789
  • 4
  • 37
  • 89
  • Well, is that a member function or a free function? – Oliver Charlesworth Dec 22 '13 at 02:56
  • 1
    Where did you put that declaration for `write`? Is it actually in the `class bmd2File` or elsewhere? We don't have enough to go on. – Joe Z Dec 22 '13 at 02:56
  • 2
    `undefined reference to foo` is not a compile error, it's a link error. Take a look at http://stackoverflow.com/questions/115703/storing-c-template-function-definitions-in-a-cpp-file?rq=1. – Casey Dec 22 '13 at 02:59
  • Okay, I edited my post to show more of the code. Is that enough to diagnose the problem? Basically, I'm new to C++ and wondering why this function is undefined. – Sharp Steel Software Dec 22 '13 at 03:00

2 Answers2

1

The error you posted is a so called linker error, which means that the function is undefined. So, here you go: your function is undefined. That's what's wrong with it.

A typical beginner's error in such case is putting the definition in .cpp file. Don't put definitions of template functions in .cpp files. Template functions should typically be defined in header files - same files that contain their declarations.

AnT
  • 302,239
  • 39
  • 506
  • 752
  • This seems to be my problem! Why must template function definitions belong only in the header files, and not in .cpp files? Oh... I see this has been asked before. Thank you! – Sharp Steel Software Dec 22 '13 at 03:05
1

The code you posted consists only of declarations. The error you got states that you are missing a [visible] definition of your write() function. That is based on the above you need to define write():

template <typename T>
void write(const T & t) const throw (bmd2Exception) {
    // you implementation goes here
}

You may have defined your function in a translation unit invisible to the instantiation in which case your question is already answered.

BTW, throw specifications except for empty specification (stating that the function isn't allowed to throw) are a Bad Idea for any sort of generic code: you have no idea whatsoever what sort of exception the generic code might need to throw.

Community
  • 1
  • 1
Dietmar Kühl
  • 145,940
  • 13
  • 211
  • 371
  • Thank you! I chose your answer because you linked to another stackoverflow that answered my question, and also because you noticed a problem with my throw specifications. – Sharp Steel Software Dec 22 '13 at 03:15