Pergunta

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?

Foi útil?

Solução

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top