1

I have a C++ namespace called ShapeBuilder containing a collection of template functions that helps draw different shapes of tiles in a tile-based game (square, line etc). Every function in this namespace used templates without error until I tried writing a non-template function - something simple like

void hey() { printf("Hey"); }

Which invoked the following errors:

1>HouseGenerator.obj : error LNK2005: "void __cdecl ShapeBuilder::hey(void)" (?hey@ShapeBuilder@@YAXXZ) already defined in Game.obj
1>WorldBuilder.obj : error LNK2005: "void __cdecl ShapeBuilder::hey(void)" (?hey@ShapeBuilder@@YAXXZ) already defined in Game.obj
  • WorldBuilder uses the namespace ShapeBuilder (and, obviously, includes ShapeBuilder.h).
  • HouseGenerator is a friend class of WorldBuilder, and includes WorldBuilder.h
  • All of the ShapeBuilder code is written in ShapeBuilder.h, which includes WorldBuilder.h
  • I have indeed used #pragma once, in all relevant classes, to prevent Recursive Inclusion.

Replacing the top code with the following will remove the error.

template <class T>
void hey() { printf("Hey"); }

So technically I could just put the template declaration in front of all of the functions, but I'm pretty sure I would burn in hell for it. Any idea what's going on?

JordanBell
  • 140
  • 1
  • 2
  • 11

1 Answers1

1

There are two options.

  1. Change the function to be inline.

    inline void hey() { printf("Hey"); }
    
  2. Declare the function in the header file but don't define it. Define it in a .cc file.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • That does work, but when it comes down to it I won't want the functions to be inline once they start getting big. Perhaps defining it in the .cpp will work, but it's killing me as to why this happens. – JordanBell May 08 '14 at 16:39
  • When you use `#include "file.h"` in a .cpp file, the cpp file gets compiled with everything that got included in it. When a .h file contains a fully defined function and the .h files gets included in multiple compilation units, the function gets defined multiple times. – R Sahu May 08 '14 at 16:42
  • Ah, okay that makes sense enough. Then why would preceding the header definition with the template declaration solve the problem? – JordanBell May 08 '14 at 16:43
  • When you have a function template, without definition, the compilation units won't know how to define a function given a template parameter. – R Sahu May 08 '14 at 16:53