0

I am relatively new to C++, so my question may have an easy answer; however, I cannot find out why my code is not working when I thought it should. Sample code is as follows.


//a.h
#ifndef A
#define A

template<class T>
class a{
public:
    a();
private:
    T str;
};

#include "a.cpp"
#endif

//a.cpp

//#ifdef A
#include "a.h"
using namespace std;

template<class T>
a<T>::a(){
    str = 'a';
}

//#endif

//driver.cpp
#include"a.h"
#include <string>
using namespace std;

void main(){
    a<string> object;
}

I have been reading information online about how to get away from errors when including template. One of it being what I am trying to achieve here: having the #include "a.cpp" in a.h. However, the samples that I have looked at still uses #include "a.h" in a.cpp, shown in the sample code. However, I am getting the function template has already been defined error. I found that using the #ifdef A and commenting out the #include "a.h" in a.cpp will help me get rid of this redefining error. But I want to understand what is happening. Shouldn't the redefinition be already taken care of by the include guard in a.h?

ew820513
  • 13
  • 4
  • 2
    Just put all your template stuff in the header file and forget about it. – Neil Kirk Oct 01 '14 at 01:15
  • 1
    As a general rule, including a .cpp file is asking for trouble. You should build your program by compiling each .cpp file by itself, once and only once. – Paul Richter Oct 01 '14 at 01:18
  • What @NeilKirk said, and [here's why](http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file). – Chris A. Oct 01 '14 at 01:19
  • Like everyone says, you should rearrange stuff. However, this still never answers the question: why do you get a redefinition? My guess is that you are trying to compile a.cpp -- not just driver.cpp. If you tried to compile a.cpp, it would include a.h, which includes a.cpp (1st def of a::a()), and then a::a() will get defined again after the include of a.h. Your commented out '#ifdef A' removes the first definition. – jsp Oct 01 '14 at 02:16
  • @ChrisA. I do not see how my code is fundamentally different from the first solution you provided in the link. The difference I notice are the `include guards`, the `tpp` instead of `cpp`, and the missing `#include .h` in cpp file. I tried making changes according to the last difference I mentioned above, but I came across more error which I think is due to the implementation file not knowing about the declaration. As for excluding the `include guard`, I will be getting circular dependency. Can you be a little bit more specific about what I am doing wrong? – ew820513 Oct 01 '14 at 07:44

2 Answers2

0

Short answer: if the implementation is not in the same header as declaration does, it won't be accessible when the compiler tries to instantiate the template.

Decipher
  • 194
  • 2
  • 11
0

That is not the way to separate the template implementation from the template declaration. You do not include the .cpp file in the .h file. Instead you simply add the .cpp file to your project file or make file so that it is compiled like all others. Then you use Explicit Template Instantiation to avoid linking errors.

Benilda Key
  • 2,836
  • 1
  • 22
  • 34