Hello everybody.Say i have a template declaration of a class:

template <DWORD Style=BS_DEFPUSHBUTTON,
          LPSTR Type="button">
class WndObj  {
   WndObj ();
 };

Now in the cpp file the definition should look something like this:

template <DWORD,LPSTR>WndObj<>::WndObj () {}
//so i can go ahead and 
typedef WndObj<> Button;

I get an unreslved external error.Any suggestions?
Thank you.

Recommended Answers

All 6 Replies

The code for templates must be only in a header file.

Which isn't exactly true, the other way is to include the .cpp file at the bottom of the .h

when doing that with visual studio you must also exclude the .cpp file from the solution explorer. Easiest/best to just include the code in the header file.

If you do that wrong you get link errors.

Not quite but in this case you're perfectly right.I know it works that way though i was curious if i cand do it this way around.Thank you.

Not quite but in this case you're perfectly right.I know it works that way though i was curious if i cand do it this way around.Thank you.

yes you can use inline files

What should go in the cpp file is the following:

template <DWORD Style,LPSTR Type>
WndObj<Style,Type>::WndObj () {}; //Definition or implementation of constructor.

template class WndObj<>; // Explicit instantiation of the default template.

typedef WndObj<> Button; //whatever this is.. doesn't matter.

The point is that if you want to use class or function templates whose code is in a cpp file that you want to compile as you usually compile cpp files (not including them at the bottom of a header file or something like that), you need to provide an explicit instantiation of the template for each possible instantiations of that template that you might want to use. Of course, in many cases, this is not possible and you have two other options: putting the code all in the header file or including the cpp file for each new template instantiation you might want to use.

That second option can be done as follows:

//in Foo.h:
#ifndef FOO_H
#define FOO_H

template <class T>
class Foo {
  public:
    Foo();
};

#endif

//in Foo.cpp
#include "Foo.h"
#include <iostream>

template <class T>
Foo<T>::Foo() {
  std::cout << "Foo constructor was called!" << std::endl;
};

//in Bar.h
#ifndef BAR_H
#define BAR_H

#include "Foo.h"

class Bar {
  private:
    Foo<Bar> Obj;
  public:
    Bar();
};

#endif

//in Bar.cpp

#include "Bar.h"

#include "Foo.cpp" //include the cpp file such that it gets compiled.

Bar::Bar() { 
  std::cout << "Bar constructor called!" << std::endl;
};

That's it, hope it helps.

I tried your first suggestion mike but i get the same error.Anyway it could be because of the const char* argument which creates linking problems.Thanks you for your time mike and firstperson.

It just hit me. Say you have:

template <LPSTR Type>
class Foo { };

How is the compiler supposed to know that these two types are the same:

typedef Foo<"my type name"> myType1;
typedef Foo<"my type name"> myType2;

It has to compare the template arguments to determine if the types myType1 and myType2 are the same. The problem is that comparing char pointers together will not succeed if the actual literal string is the same, the pointer actually needs to be the same, which will never happen.

So, that confirms a little hunch I had when looking at your code that it was kinda weird to see a pointer type as a template argument. I suggest you use only non-pointer primitive types as template arguments.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.