Page 1 of 1

compiling discrepencies

Posted: Sat Oct 06, 2007 11:20 pm
by eboyd
when i compile in devc++ (with no project made or anything)
i can do the following:

Code: Select all

template <typename T> class myClass
{
    public:

        myClass();
  
        ...
};
and then have a source file with:

Code: Select all

template <typename T> myClass<T>::myClass<T>()
{
    ...
}

but when i do the same thing under cygwin (gcc) it tells me i have undefined referneces to myClass<T>::myClass() ????

In both I'm compiling w/ -ansi -pedantic -Wall -Wextra -Werror


What's going on?????

Posted: Sun Oct 07, 2007 5:42 am
by Candy
IT should never generate references to the uninstantiated template. If you want to use it however, the template has to be joined with the header or compiled separately (as export, which your compiler doesn't support).

I think it might be a side-effect of how you invoke the compiler.

Posted: Mon Oct 08, 2007 12:59 am
by os64dev
In general it is bad practice to separate a template declaration and implementation in a h and c file, just put them in one h file. Personally i prefer the separation in two files but it gives a lot of problems. Though i didn't check pragma interface and pragma implementation yet.

Posted: Mon Oct 08, 2007 2:16 am
by Solar
Seperating declaration and definition is not a bad idea at all, it is elementary to making C++ code maintainable.

The problem is that a template definition can only be made into code if the compiler "knows" the actual type with which to instantiate the template. There are ways around it, which is why the "export" keyword was added to the standard, but since none of the "mainstream" compilers actually support "export", you are stuck with writing your template definitions in header files.

Posted: Mon Oct 08, 2007 3:32 am
by os64dev
Seperating declaration and definition is not a bad idea at all, it is elementary to making C++ code maintainable.
Ho, Ho, i only mentioned that for templates this is a bad thing to do. For non-templates it is the only thing to do unless you want better performance then you inline the implementation

Posted: Mon Oct 08, 2007 5:14 am
by Solar
os64dev wrote:
Seperating declaration and definition is not a bad idea at all, it is elementary to making C++ code maintainable.
Ho, Ho, i only mentioned that for templates this is a bad thing to do.
Yes, but not because it would be a bad design decision, but because most compilers are plainly broken in that regard.

Posted: Mon Oct 08, 2007 6:37 pm
by eboyd
I find the following interesting:

I can get around the whole separating my template definition into a .h and a .cpp file like I would any normal class with the whole:

Code: Select all

template returnType myFunction<int>();
thing.

But it only seems to work with my constructors. My member functions (and I'm talking about my public interface) still doesn't like this workaround. The whole thing has me seriously vexed. I know I shouldn't expect my compiler to like the idea of separating the implementation, bu it just feels wrong to me.

Posted: Tue Oct 09, 2007 12:57 am
by os64dev
did you try #pragma interface and #pragma implementation? Don't know of they actually work but they seem related.

or what i saw on redhat:

Code: Select all

#include "Foo.h"
#include "Foo.cc"

template class Foo<int>;
template ostream& operator << (ostream&, const Foo<int>&);

Posted: Thu Oct 18, 2007 1:12 am
by AndrewAPrice
I have the same problem. Consider this:
vector3d.h:

Code: Select all

#include "matrix.h"
// can't use "class Matrix;" because we're accessing the properties of Matrix within this file

template<class T>
class Vector3D<T>
{
   // ...
   Matrix CreateTranslationMatrix() // this is a template class so I can't put this in a .cpp
  {
     Matrix m;
     // access internal properties of m here
     return m;
  }
  // ...
}
matrix.h:

Code: Select all

#include "vector3d.h" // I can't define a prototype for Vector3D<int>

class Matrix
{
    // ...
    Vector3D<int> GetTranslation(); // the code for this is in Matrix.cpp
    // ...
}
How could I do this? (I could make GetTranslation a static function inside Vector3Df but I do not want to do this.)

Posted: Thu Oct 18, 2007 11:23 am
by Candy
MessiahAndrw wrote:// can't use "class Matrix;" because we're accessing the properties of Matrix within this file
Are you sure? The template should only be instantiated after including matrix, which would make the function defined. I'm not certain though.

Posted: Thu Oct 18, 2007 3:23 pm
by os64dev
not really sure but :

Code: Select all

class vector3d;

class matrix {

vector3d<int> getTranslation(void);
}

#include "vector3d.h"

vector3d<int> matrix::getTranslation(void){
}

Code: Select all

class matrix;

template< typename t>
class vector3d {
    matrix CreateMatrix(void);
}

#include "matrix.h"

template< typename t>
matrix vector3d<t>::CreateMatrix(void) {
}

Posted: Thu Oct 18, 2007 5:32 pm
by AndrewAPrice
Candy wrote:
MessiahAndrw wrote:// can't use "class Matrix;" because we're accessing the properties of Matrix within this file
Are you sure? The template should only be instantiated after including matrix, which would make the function defined. I'm not certain though.
That gives me "error C2027: use of undefined type 'MGF::Core::Matrix'" in vector3d.h.
os64dev wrote:not really sure but :

Code: Select all

class vector3d;

class matrix {

vector3d<int> getTranslation(void);
}

#include "vector3d.h"

vector3d<int> matrix::getTranslation(void){
}

That gives me (in matrix.h):
error C2059: syntax error : '<'
error C2238: unexpected token(s) preceding ';'
os64dev wrote:

Code: Select all

class matrix;

template< typename t>
class vector3d {
    matrix CreateMatrix(void);
}

#include "matrix.h"

template< typename t>
matrix vector3d<t>::CreateMatrix(void) {
}
That gives me:
error C2065: 'T' : undeclared identifier
error C2955: 'MGF::Core::Vector3D' : use of class template requires template argument list
error C2509: 'CreateMatrix' : member function not declared in 'MGF::Core::Vector3D'

I'm thinking about giving up on templates.

Posted: Thu Oct 18, 2007 5:34 pm
by AndrewAPrice
os64dev wrote:not really sure but :

Code: Select all

class vector3d;

class matrix {

vector3d<int> getTranslation(void);
}

#include "vector3d.h"

vector3d<int> matrix::getTranslation(void){
}

Code: Select all

class matrix;

template< typename t>
class vector3d {
    matrix CreateMatrix(void);
}

#include "matrix.h"

template< typename t>
matrix vector3d<t>::CreateMatrix(void) {
}