Template classes <-> separate class compile

Hi,

I have a subsystem where all classes are compiled separate, and runnable objects are created by linking everything (main and all classes) together.

I want to use a template-class (T) to extend the subsystem. I know for which typenames (f.e. A and B) a class should be compiled.

Can I compile the 2 (template-)classes loose ? ... and so stick to the compile-model described at the beginning of this post.

Thanks.
http://stackoverflow.com/questions/8130602/using-extern-template-c0x
And why just make it non-templated if you want it to exist only for two datatypes?
Also see:

[35.12] Why can't I separate the definition of my templates class from its declaration and put it inside a .cpp file?
http://www.parashift.com/c++-faq/templates-defn-vs-decl.html

Templates and separate compilation
http://stackoverflow.com/questions/9191210/templates-and-separate-compilation

Andy

PS Both from first page of google of "Template classes <-> separate class compile"
Last edited on
Thanks for the links.
Let me show you with a small int-example what I'm trying to do/accomplisch.
int is later on replaced with a record, and MYCLASS is extended with all kinds of getters/setters for the specific record ... so please don't care/react on the int.


SOURH (template class) :
1
2
3
4
5
6
template <typename T>  class clsC {
public:
    clsC (T arg) {
        cout << "template arg: " << arg << "\n";
    }
};



SOURC (int class of template) :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
using namespace std;

#include "sourh"

class MYCLASS : public clsC<int>
{
public:
    MYCLASS(int argInt): clsC<int>(argInt) {
    }
 
protected:
 
private:
 
};



SOURCH (H-file for MYCLASS) :
1
2
3
4
5
6
7
8
9
10
namespace nsp_MYCLASS {
 
    class MYCLASS
    {
      private:
 
      public:
        MYCLASS(int number);
    };
}



SOURM (main program) :
1
2
3
4
5
6
7
8
9
10
#include <iostream>
using namespace std;
 
#include "sourch"
using namespace nsp_MYCLASS;
 
int main (int argc, char* argv[]) {

    MYCLASS a (2);
}



The compiles of SOURC and SOURM go oke. But the linker is giving an error :

**** ERROR **** [1210]:
SOURM: In function `main':
SOURM(.text._168869328+0x182): unresolved reference to
__ct__Q2_11nsp_MYCLASS7MYCLASSFi (C++ mangling of
nsp_MYCLASS::MYCLASS::(int)).


What am I doing wrong ? How to get above example working ?

Thanks.
1) Implementation should be in same namespace as definition
2) You should not double-declare class (you didn't include header into implementation, so it won't cause errors here)
3) (In your case) Declarations should be identical: class MYCLASS and class MYCLASS : public clsC<int> is two distinct classes.

You probably can do:
1
2
3
4
5
6
7
class MYCLASS; //Forward declaration

int main()
{
    MYCLASS* a = new MYCLASS; //Pointer members are allowed to use
                              //Without full declaration of class
}

Last edited on
explicit template instantiation http://www.cplusplus.com/forum/articles/14272/

> And why just make it non-templated if you want it to exist only for two datatypes?
because I would have to repeat the code for that two types.

> MYCLASS* a = new MYCLASS;
┬┐what are you trying to show?
Following on from what MiiNiPaa said, it looks like you mean?

Where SOURH, SOURM are as before...

SOURC

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
using namespace std;

#include "sourch"

// provide missing implementation of constructor

nsp_MYCLASS::MYCLASS::MYCLASS(int argInt)
: clsC<int>(argInt)
{
}


SOURCH

1
2
3
4
5
6
7
8
9
10
11
12
#include "sourh" // must see base class declaration

namespace nsp_MYCLASS {
 
    class MYCLASS : public clsC<int> // and derive from it
    {
      private:
 
      public:
        MYCLASS(int number);
    };
}


SOURM

template arg: 2
Press any key to continue . . .


Or were you trying to do something else?

Andy

PS @MiiNiPaa while you can pass pointers to objects around without seeing the class declaration, the declaration is required for construction -- as the compiler must be told about the memory layout of the class -- and use of the class -- so the function signature is known.
Last edited on
Hi Andy,

Great show ... you nailed it ... this works ... many thanks !!!

Greetz
One additional question, you coded :

1
2
#include "sourch"
nsp_MYCLASS::MYCLASS::MYCLASS(int argInt)


is there an advantage compared to :

1
2
3
4
#include "sourch"
using namespace nsp_MYCLASS;

MYCLASS::MYCLASS(int argInt)


Last edited on
Yes. You will not run into name collisions. They are rare, but if it happens it is often pain in the back to find out.
is there an advantage compared to :

A using statement like

using namespace nsp_MYCLASS;

just imports the symbols (i.e. the various names) into the global namespace, so they can be used without having to qualify them with the name of the namespace.

But an implementation be actually in the namespace, so must either include the namespace like above

1
2
3
4
5
6
7
8
#include "sourch"

nsp_MYCLASS::MYCLASS::MYCLASS(int argInt)
{
    // etc
}

//etc 


or be defined inside it namespace Name { }, like

1
2
3
4
5
6
7
8
9
10
11
12
#include "sourch"

namespace nsp_MYCLASS {

nsp_MYCLASS::MYCLASS::MYCLASS(int argInt)
{
    // etc
}

// etc

} // end namespace nsp_MYCLASS 


(When I use this second approach, I don't indent the classes wrt to the namespace. And I always comment the end of the namespace, so I don't loose it.)

Andy
Last edited on
isn't there one 'nsp_MYCLASS' too much in the last code-example ? Couldn't it be like below ?

1
2
3
4
5
6
7
8
9
10
#include "sourch"

namespace nsp_MYCLASS {

MYCLASS::MYCLASS(int argInt)
{
    // etc
}

} // end namespace nsp_MYCLASS 
Topic archived. No new replies allowed.