7

I am using this class with--all except for one--template member functions, which will be used in a project with multiple source files which get linked on compilation. The template type is unknown and can take just about any type to it. In this case I have two source files which use the class, therefore the header file with the class declaration and definition is #include:ed in both source files. I then get the error "multiple definition" at the non-template member function declaration of the class. I presume that is because it is being defined twice during the linking process since both source files have a definition of the non-template member function. Imagine the non-sense scenario below:

Note: Assume all files are include guarded and iostream is #include:ed wherever required.

foo.hpp

class foo
{
public:
    template <typename X>
    void f(X);

    void ff ();
};

#include "foo.tpp"

foo.tpp

template <typename X>
void foo::f(X val)
{
    cout << val;
}

void foo::ff() // multiple definitions
{
    cout << sizeof(*this);
}

main2.cpp

#include "foo.hpp"

main.cpp

#include "foo.hpp"

int main()
{
    return 0;
}

Adding the inline keyword to the function definition seems to solve this error, though I don't want to use it because I've got other non-template member functions suffering the same issue which are way larger and are referenced in multiple parts of the code. Is there any work-around or valid way to do what I'm trying to do? Thanks in advance!

Hello World
  • 423
  • 5
  • 15
  • 1
    For what it's worth, all of the templated functions are already implicitly `inline` unless fully specialised. – Justin Time - Reinstate Monica Aug 05 '16 at 19:53
  • Ouch. Definitely worth mentioning! I'll keep that in mind. Thank you very much for the input. – Hello World Aug 05 '16 at 20:42
  • 1
    You're welcome. It's because templated code needs to be visible in any translation unit which uses it, so the compiler is able to create actual code from it, whch in turn means that templated code need to be `inline` to allow multiple identical definitions. A fully specialised templated function is treated as a normal function, though, because it doesn't need to have any template parameters filled in, and thus can be treated as actual code (allowing it to be linked to, unlike non-specialised templated functions). – Justin Time - Reinstate Monica Aug 06 '16 at 16:56

1 Answers1

7

Create a third, foo.cpp file for the definitions of non-template functions that are not declared as inline. The class is non-template, so you don't need to define all its member functions in the header, just the template ones (or maybe not).

Community
  • 1
  • 1
LogicStuff
  • 19,397
  • 6
  • 54
  • 74
  • 1
    Simple solutions are always lurking around the corner and many times I tend to miss them. No way I would have thought of that, and this issue has been bugging me for a week until I decided to drop my pride and ask. Very clever little solution. I guess I got some more compiler understanding to do. Thanks a ton! – Hello World Aug 05 '16 at 19:31