2

First of all thanks in advance for your time. I have a little problem with templates (I'm quite new in this templates thing).

The code is in C++ compiled (or at least tried to) with Visual studio 2012.

main.h:

class Main
{
public:

template<class T>
static void foo(T param1);
};

main.cpp

#include "main.h"
template<class T> 
static void Main::foo(T param1)
{
  // do things
}

other.h

#include "main.h"

class Other
{
public:
  void foo2();
};

other.cpp

#include "other.h"

void Other::foo2()
{
  int var1 = 10;
  Main::foo(var1); // Here is the link error.
}

Well the problem as you probably know the quite common unresolved external symbol, so I've looked around the web in order to find something which can help me to understand and solve this link error and I've found a few things that I've already tried but without result.

I've tried:

1- Implement the foo function in the .h file

2- Use inline keyword

3- Tried with export (which actually is not supported by the compiler)

but none of those approachs seems to work with me, so obviously I'm doing something wrong or I'm missing something.

Remember that the templated function must be declared in "Main" class. Move the function to the "Other" class will not help me despite that can solve the error.

Error:

Error 5 error LNK2019: unresolved external symbol "public: static void __fastcall CGame::Push(char *,int,unsigned int &)" (??$Push@H@CGame@@SIXPADHAAI@Z) referenced in function "public: void __thiscall ClientManager::RequestLogin(int,char *)" (?RequestLogin@ClientManager@@QAEXHPAD@Z)

Where CGame would be Main, Push = foo(), ClientManager = Other and RequestLogin = foo2.

Thanks again for your time.

Daniel Lauro
  • 35
  • 1
  • 6
  • 3
    #1 is what you should use http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file. The others won't do. Why it's not working, I don't know. Why don't you post what it looks like, and what you get when you use #1? – R. Martinho Fernandes Aug 23 '13 at 16:04
  • Templates need their *definition* (not just declaration) available to the *caller* to allow the compiler to properly generate the template expansion. The article linked by Mr. Fernandes in the prior comment will explain in further detail, but unless the entire template *and* its usage is both declared *and* defined in a single .cpp file, you need to put the body in the .h file either in-class or as an `inline`. – WhozCraig Aug 23 '13 at 16:18
  • Maybe the problem was that I "forgot" (or didn't take in mind) to add the keyword inline on the definition in the header file. Now is working like a charm. I think I was to 'burned' to think properly. Thanks you both! – Daniel Lauro Aug 23 '13 at 16:51
  • 1
    Anyway you should remove that "`static`" from the function _definition_ (outside of the class it means "internal linkage" i.e. "local to the current translation unit"). Compare: http://ideone.com/CT6sW4 (`error: cannot declare member function ‘static void Main::foo(T)’ to have static linkage`) vs http://ideone.com/4Nydk4 (of course you can alternatively define it directly inside the class: http://ideone.com/ZPs690 ) – gx_ Aug 23 '13 at 18:21
  • @gx_ even if I want to call that function from another class without instantiate a new Main (in this case) object I should remove the static? – Daniel Lauro Aug 24 '13 at 03:27
  • 1
    @DanielLauro Specifying `static` for _both_ the in-class declaration _and_ the out-of-class definition is invalid (it should cause a compilation error); the two "static" mean _two different things_ (yes that's confusing) [ see http://ideone.com/lghy6m ]. So we must specify `static` for the in-class declaration but _not_ repeat it for the out-of-class definition [ see http://ideone.com/bcAXTq ]. Alternatively we can "merge" the definition into the in-class declaration [ see http://ideone.com/mwBDQX ]. The linked code examples _don't_ instantiate a new Main. – gx_ Aug 24 '13 at 20:43

0 Answers0