-1

I have a very weird error: I have a pair of .h and .cpp files that contain some functions and constants. When I try to compile it, g++ says "undefined reference" to the function. The function prototype and definition seem to be the same. I have commented everything out except the necessary lines, and g++ still complains about it.

My program is currently (after commenting everything out):

main.cpp

#include "a.h"

int main(){
    makehex(10);

    return 0;
}

a.h

#include <iostream>
#include <sstream>

#ifndef __A___

static const std::string b = "01";
static const std::string d = b + "23456789";
static const std::string h = d + "abcdef";

template <typename T> std::string makehex(T value, unsigned int size = 2 * sizeof(T));
#endif

a.cpp

#include "a.h"

template <typename T> std::string makehex(T value, unsigned int size){
    // Changes a value to its hexadecimal string
    if (!size){
        std::stringstream out;
        out << std::hex << value;
        return out.str();
    }
    std::string out(size, '0');
    while (value && size){
        out[--size] = h[value & 15];
        value >>= 4;
    }
    return out;
}

There is only 1 function. I dont see how this could error.

Im compiling with g++ -std=c++11 main.cpp a.cpp and getting the errors:

main.cpp:(.text+0x1a): undefined reference to `std::string makehex<int>(int, unsigned int)'
collect2: error: ld returned 1 exit status

Is it because of the template? If so, how do i fix it?

3
  • possible duplicate of Template issue causes linker error (C++) Commented Jul 19, 2013 at 20:03
  • You're using a reserved identifier. Commented Jul 19, 2013 at 20:05
  • Bad Karma: declaring static variables in a header file. Commented Jul 19, 2013 at 20:06

3 Answers 3

2

Common template mistake. The compiler needs to know the definition of the template at compile time: thus, the definition of the template function must be in the header file.

Sign up to request clarification or add additional context in comments.

3 Comments

Or, a specialization of the template must be implemented in the .cpp file.
@calccrypto What do you think template <typename T> std::string makehex(T value, unsigned int size) is?
@H2CO3 Ha yeah, that is true, that screwed me up the first time i did it.
2

You need to understand that templates aren't code themselves but it tells the compiler how to generate code that other parts of your program can use. For the compiler to be able to do that automatically it must have seen the definition of that template at the point of instantiation.

But in your existing setup, only the declaration of makehex<T>() is visible in main.cpp. The actual definition of makehex<T>() is squirreled away in a.cpp which main doesn't know about during compilation (it's in a different translation unit).The easy fix for this is to move implementation of makehex<T>() from a.cpp into a.h.

Comments

1

A template function is only emitted when you actually instantiate the template. You are attempting to do this in the main function, using the call makehex(10).

You have included "a.h" in the main.cpp file, so when compiling main.cpp, you have access to the declaration of the function. However, the compiler is not able to access the definition because it's in a different file (a.cpp) which hasn't been included.

The short-term fix is to #include "a.cpp" in main.cpp. However, the long-term fix is not to have .cpp files for template function definitions - put it all in the header (.h) file. (This does NOT apply to ordinary functions/classes etc).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.