1

Class

The following code works great (example taken from cppreference.com):

class SomeClass
{
public:
    void tprintf(const char* format) // base function
    {
        std::cout << format;
    }

    template<typename T, typename... Targs>
    void tprintf(const char* format, T value, Targs... Fargs) // recursive variadic function
    {
        for (; *format != '\0'; format++) {
            if (*format == '%') {
                std::cout << value;
                tprintf(format + 1, Fargs...); // recursive call
                return;
            }
            std::cout << *format;
        }
    }
};

void main()
{
    SomeClass someClass;
    someClass.tprintf("% world% %\n", "Hello", '!', 123);
}

Lib

When I try to replicate this by making a lib of the SomeClass class i get an unresolved external symbol error:

SomeClass.h

class SomeClass
{
public:

    void tprintf(const char* format);

    template<typename T, typename... Targs>
    void tprintf(const char* format, T value, Targs... Fargs);
}

SomeClass.cpp

void SomeClass::tprintf(const char* format) // base function
{
    std::cout << format;
}

template<typename T, typename... Targs>
void SomeClass::tprintf(const char* format, T value, Targs... Fargs) // recursive variadic function
{
    for (; *format != '\0'; format++) {
        if (*format == '%') {
            std::cout << value;
            tprintf(format + 1, Fargs...); // recursive call
            return;
        }
        std::cout << *format;
    }
}

main.cpp

#include <ibppWrapper.h>

void main()
{
    SomeClass someClass;
    someClass.tprintf("% world% %\n", "Hello", '!', 123);
}

The unresolved external symbol error:

error LNK2019: unresolved external symbol "public: void __thiscall SomeClass::tprintf<char const *,char,int>(char const *,char const *,char,int)" (??$tprintf@PBDDH@SomeClass@@QAEXPBD0DH@Z) referenced in function _main

Conclusion

It seems like the linker is searching for a function in my SomeClass lib with the exact parameters:

SomeClass::tprintf<char const *,char,int>(char const *,char const *,char,int) 

Whilst it should find or search for:

SomeClass::tprintf<T,... Targs>(char const *,T, ... Targs)

Questions

Is my conclusion correct? Is this expected behavior? Is there a Solution for this?

Steve Van Opstal
  • 1,062
  • 1
  • 9
  • 27
  • It's probably due to the fact that you generally don't separate templated functions into two files. It's possible, of course. If you do, then you need to do some more legwork to make sure it compiles. I'm not sure you're including/linking things correctly is my point. – AndyG Dec 07 '13 at 19:31
  • Which compiler are you using? did you included SomeClass.cpp to the compiler? – Didac Perez Parera Dec 07 '13 at 19:36
  • @AndyG I also suspected a linking issue but the program runs fine when the templated functions are written inline in SomeClass.h. I include the .lib, .pdb and .h. – Steve Van Opstal Dec 07 '13 at 19:44
  • @DídacPérez is the .cpp necessary when i already included the rest, do you also know why this should be included for templated functions and not for others? – Steve Van Opstal Dec 07 '13 at 19:45
  • 2
    Function templates are not functions, but templates. In order to create a function from a function template, the compiler needs to instantiate it. For every different set of template arguments, there needs to be an instantiation. In your case, the compiler is able to instantiate the declaration, but not the definition of `SomeClass::tprintf` in `main.cpp`, because the definition isn't visible in the translation unit formed from `main.cpp`. Either put the function template's definition in the header file or provide some explicit instantiations. – dyp Dec 07 '13 at 19:51

0 Answers0