Archived

This topic is now archived and is closed to further replies.

Templates and .h/.cpp files

This topic is 5016 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

(MSVC++.NET) Does anyone have a clue why I can make templates if the whole thing is in a .h file, but when I place the non-header part in a .cpp files the compiler will start spitting out errors like: Main.obj : error LNK2019: unresolved external symbol "public: __thiscall CDatabase::CDatabase(void)" (??0?$CDatabase@VCTest@@@@QAE@XZ) referenced in function _main So the following would work:
### IN DATABASE.H ###

template <class TDatabase>
class CDatabase
{
public:
		 CDatabase ( void ); /* Constructor */
		~CDatabase ( void ); /* Destructor  */

// private:

};

/* Constructor */
template <class TDatabase>
CDatabase <TDatabase> ::CDatabase ( void )
{
}

/* Destructor */
template <class TDatabase>
CDatabase <TDatabase> ::~CDatabase ( void )
{
}

### IN MAIN.CPP ###
#include "Database.h"

void main ( void )
{
	CDatabase <CTest> *pDatabase;

	pDatabase = new CDatabase <CTest> ( );

	delete pDatabase;
	pDatabase = 0;
}


But this would not:

   
### IN DATABASE.H ###

template <class TDatabase>
class CDatabase
{
public:
		 CDatabase ( void ); /* Constructor */
		~CDatabase ( void ); /* Destructor  */

// private:

};

### IN DATABASE.CPP ###
#include "Database.h"

/* Constructor */
template <class TDatabase>
CDatabase <TDatabase> ::CDatabase ( void )
{
}

/* Destructor */
template <class TDatabase>
CDatabase <TDatabase> ::~CDatabase ( void )
{
}

### IN MAIN.CPP ###
#include "Database.h"

void main ( void )
{
	CDatabase <CTest> *pDatabase;

	pDatabase = new CDatabase <CTest> ( );

	delete pDatabase;
	pDatabase = 0;
}
I really can't stand weird things like these, is it anything I did wrong, or anyway to bypass this, because I like to be consistent and headers are headers and are not to contain source. [edited by - Siaon on March 24, 2004 9:53:48 AM]

Share this post


Link to post
Share on other sites
I had posted this question a while back too.

You need to have all the implementation for the classes functions in the header file as the linker doesn''t know what sort of data you will be using in your template.

Share this post


Link to post
Share on other sites
You can''t split templates into multiple files. You should be able to, according to the standard, using the export keyword, but Comeau C++ is the only compiler I''ve ever heard of that supported that feature; it''s just too much trouble to implement.

So stick your entire template structure back in the header and enjoy life!

Share this post


Link to post
Share on other sites
It''s not excactly enjoy life ^^ It''d be breaking my standard whic is horrible enough, also the templates can grow quite large since I derive from them and specialize and the whole bunch, so it adds greatly to the compiling time.

This is a major annoyance, but alas, thanks for the quick replies though, basically they force you to recompile the entire bunch even if you didnt instantiate a new template instance, while they just could check if you did and only then build a new .obj

Ah well, guess this is easier on them.

Share this post


Link to post
Share on other sites
Anyway, how excactly do I EXPORT it in this example so I could use it?

Hmmm, MSDN says:

quote:

The export keyword is not supported on templates. For example, the following sample will not compile:

export template void fun(T);
export template class A;



[edited by - Siaon on March 24, 2004 10:28:31 AM]

Share this post


Link to post
Share on other sites
You can split the source in two files (H and CPP), but, when you use these files (in main.cpp, for example), you must to include the CPP file. It''s strange, but it works.

However, because you are using templates, no object file will be generated for these source files. So, the source will be re-compiled each time.

//// IN DATABASE.H
template
class CDatabase
{
public:
CDatabase ( void ); /* Constructor */
};

//// IN DATABASE.CPP
/* Constructor */
template
CDatabase <tdatabase> ::CDatabase ( void )
{
// code
}

//// IN MAIN.CPP
#include "database.cpp"



Eduardo
[<(~)>]

Share this post


Link to post
Share on other sites

quote:
Original post by ewbasso
You can split the source in two files (H and CPP), but, when you use these files (in main.cpp, for example), you must to include the CPP file. It''s strange, but it works.

However, because you are using templates, no object file will be generated for these source files. So, the source will be re-compiled each time.

//// IN DATABASE.H
template
class CDatabase
{
public:
CDatabase ( void ); /* Constructor */
};

//// IN DATABASE.CPP
/* Constructor */
template
CDatabase <tdatabase> ::CDatabase ( void )
{
// code
}

//// IN MAIN.CPP
#include "database.cpp"



Eduardo
[<(~)>]


Including the .cpp file will work, but I prefer to use .inl files. I find it a bit cleaner and avoids confusion.

Share this post


Link to post
Share on other sites