compiling discrepencies

Programming, for all ages and all languages.
Post Reply
User avatar
eboyd
Member
Member
Posts: 97
Joined: Thu Jul 26, 2007 9:18 am
Location: United States

compiling discrepencies

Post 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?????
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Post 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.
User avatar
os64dev
Member
Member
Posts: 553
Joined: Sat Jan 27, 2007 3:21 pm
Location: Best, Netherlands

Post 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.
Author of COBOS
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Post 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.
Every good solution is obvious once you've found it.
User avatar
os64dev
Member
Member
Posts: 553
Joined: Sat Jan 27, 2007 3:21 pm
Location: Best, Netherlands

Post 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
Author of COBOS
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Post 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.
Every good solution is obvious once you've found it.
User avatar
eboyd
Member
Member
Posts: 97
Joined: Thu Jul 26, 2007 9:18 am
Location: United States

Post 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.
User avatar
os64dev
Member
Member
Posts: 553
Joined: Sat Jan 27, 2007 3:21 pm
Location: Best, Netherlands

Post 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>&);
Author of COBOS
User avatar
AndrewAPrice
Member
Member
Posts: 2299
Joined: Mon Jun 05, 2006 11:00 pm
Location: USA (and Australia)

Post 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.)
My OS is Perception.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Post 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.
User avatar
os64dev
Member
Member
Posts: 553
Joined: Sat Jan 27, 2007 3:21 pm
Location: Best, Netherlands

Post 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) {
}
Author of COBOS
User avatar
AndrewAPrice
Member
Member
Posts: 2299
Joined: Mon Jun 05, 2006 11:00 pm
Location: USA (and Australia)

Post 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.
My OS is Perception.
User avatar
AndrewAPrice
Member
Member
Posts: 2299
Joined: Mon Jun 05, 2006 11:00 pm
Location: USA (and Australia)

Post 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) {
}
My OS is Perception.
Post Reply