Template class overloaded operator

Started by
7 comments, last by MaulingMonkey 18 years, 8 months ago
Would anyone know the reason for these errors... /////////////////////////////////////////////////////////////////////////////// In file included from myInclude.h:7, from main.cpp:1: cl_3dPoint.h:81: error: expected init-declarator before '&' token cl_3dPoint.h:81: error: expected `;' before '&' token cl_3dPoint.h:36: warning: inline function `nmGeometric::cl_3dPoint<tType>& nmGeometric::cl_3dPoint<tType>::operator=(const nmGeometric::cl_3dPoint<tType>&) const [with tType = double]' used but never defined make.exe: *** [main.o] Error 1 Execution terminated /////////////////////////////////////////////////////////////////////////////// The following is my code, compiled with the mingw compiler system included with dev-c++. What is weird is that when I move the implementation of the overloaded assignment operator into the body of the class and remove the const keyword at the very end, it compiles perfectly. But when I try to do the same with the implemenation outside the class I get errors. Does anyone know why? main.cpp


#include "myInclude.h"
using namespace nmGeometric;

int main()
{
    // CONSTRUCTORS
    cl_3dPoint < double >   objPointB;
    cl_3dPoint < double >   objPointC(-2, 3, 8);

    // ASSIGNMENT OPERATOR
    objPointB = objPointC;

    system("PAUSE");
    return 0;
}


myInclude.h

#ifndef __MY_INCLUDE_H__
#define __MY_INCLUDE_H__

#include <iostream>
using namespace std;

#include "cl_3dPoint.h"

#endif // __MY_INCLUDE_H__


cl_3dPoint.h

#ifndef __CLASS_3D_POINT__
#define __CLASS_3D_POINT__

namespace nmGeometric
{
    template <typename tType>
    class cl_3dPoint
    {
private:

protected:

public:
    //
    // MEMBER VARIABLES
    //
    tType x, y, z;
    
    //
    // MEMBER FUNCTIONS
    //

    // DESTRUCTOR
    ~cl_3dPoint();

    // CONSTRUCTOR
    cl_3dPoint();

    // CONSTRUCTOR
    cl_3dPoint(const tType & X, const tType & Y, const tType & Z);

    // COPY CONSTRUCTOR
    cl_3dPoint(const cl_3dPoint < tType > & param);

    // =
    inline cl_3dPoint & operator = (const cl_3dPoint < tType > & point_1) const;

    }; // cl_3dPoint


    // *************************************************************************
    // DESTRUCTOR
    // *************************************************************************
    template < typename tType >
    cl_3dPoint < tType >::~cl_3dPoint()
    {
    }

    // *************************************************************************
    // CONSTRUCTOR FOR A 3D POINT AT THE ORIGIN
    // *************************************************************************
    template < typename tType >
    cl_3dPoint < tType >::cl_3dPoint(): x(static_cast < tType > (0)),
                                        y(static_cast < tType > (0)),
                                        z(static_cast < tType > (0)){}
                                        
    // *************************************************************************
    // CONSTRUCTOR FOR INITIALIZING A 3D POINT.
    // *************************************************************************
    template < typename tType >
    cl_3dPoint < tType >::cl_3dPoint(const tType & X, const tType & Y, const tType & Z)
    {
        this->x = X;
        this->y = Y;
        this->z = Z;
    }

    // *************************************************************************
    // COPY CONSTRUCTOR
    // *************************************************************************
    template < typename tType >
    cl_3dPoint < tType >::cl_3dPoint(const cl_3dPoint < tType > & param) : x(param.x),
                                                                           y(param.y),
                                                                           z(param.z){}

    // *************************************************************************
    // =
    // ASSIGNMENT OPERATOR. ASSIGNS ONE POINT TO ANOTHER
    // *************************************************************************
    template < typename tType >
    inline cl_3dPoint & cl_3dPoint < tType >::operator = (const cl_3dPoint < tType > & point_1) const
    {
        //  MAKE SURE THERE IS NO SELF ASSIGNMENT OF THE SAME POINT TO ITSELF
        if (this != &point_1)
        {
            this->x = point_1.x;
            this->y = point_1.y;
            this->z = point_1.z;
        }
        return *this;
    }
} // nm_geometric

#endif // __CLASS_3D_POINT__


Advertisement
Look at the function signature for your assignment operator:

inline cl_3dPoint & cl_3dPoint < tType >::operator = (const cl_3dPoint < tType > & point_1) const

You have declared the function as const. That means the this pointer is const within that function, which means you cannot modify any members of the function through it, and you can only call other const member functions within it. This makes the xyz assignments you're doing within the assignment operator illegal. Remove the const keyword, it shouldn't be there at all. It makes absolutely no sence on an assignment operator. If you don't understand why, I'd suggest you read up on cv qualifiers.
Not exactly sure, but there's one very obvious bug: the operator= function should NOT be a const function!!! You should be getting compile errors when you try to assign this->x/y/z.

This: inline cl_3dPoint & operator = (const cl_3dPoint < tType > & point_1) const;

Would (if x/y/z were made mutable, e.g. mutable tType x,y,z) allow:

const cl_3dPoint< double > foo( 1.0 , 2.0 , 3.0 );
foo = cl_3dPonit< double >( 3.0 , 2.0 , 1.0 ); //we shouldn't be allowed to reassign a constant, yet here we are doing just that!!!

Solution: remove the const specifier:

inline cl_3dPoint & operator = (const cl_3dPoint < tType > & point_1) const;

template < typename tType >
inline cl_3dPoint & cl_3dPoint < tType >::operator = (const cl_3dPoint < tType > & point_1) const
{
....


If I had to guess I'd say you're compiler is getting confused by this, prehaps along with the combination of the inline keyword, and is for some reason just not putting two and two together. Nothing else wrong that I see off the bat, it'd be nice if you could mark the lines with the errors with their number, so I don't have to grab an editor to do that myself... :-).
Good points. But when I make that function as simple as follows...

    cl_3dPoint & operator = (cl_3dPoint < tType > point_1);


template < typename tType >    cl_3dPoint & cl_3dPoint < tType >::operator = (cl_3dPoint < tType > point_1)    {        //  MAKE SURE THERE IS NO SELF ASSIGNMENT OF THE SAME POINT TO ITSELF        if (this != &point_1)        {            this->x = point_1.x;            this->y = point_1.y;            this->z = point_1.z;        }        return *this;    }


... I get the same errors unless the I move the implementation into the class, like so...

cl_3dPoint & operator = (cl_3dPoint < tType > point_1)    {        //  MAKE SURE THERE IS NO SELF ASSIGNMENT OF THE SAME POINT TO ITSELF        if (this != &point_1)        {            this->x = point_1.x;            this->y = point_1.y;            this->z = point_1.z;        }        return *this;    }


Any idea why this compiles while the above does not?
Quote:Good points. But when I make that function as simple as follows...

A prototype declaration for a templated function requires the template keyword and argument list to be included. Try this instead:

template <typename tType> cl_3dPoint & operator = (cl_3dPoint < tType > point_1);
Nope, the template keyword and argument list are included at the begining of the class, so that doesn't really solve the compile issue. I'll just go ahead and move the implementation into the class itself. This just bugs the hell out of me.
Your compiler is probably wondering why you're asking it to return a template rather than an instantiation of the template:
template < typename tType >class cl_3dPoint{	public:		// inside a template class definition the class name without a template parameter		// is synonomous with the class name templated on the template parameter, so the		// following four declarations have identical meaning:		inline cl_3dPoint & operator=(cl_3dPoint< tType > const & point_1);//		inline cl_3dPoint & operator=(cl_3dPoint const & point_1);//		inline cl_3dPoint< tType > & operator=(cl_3dPoint const & point_1);//		inline cl_3dPoint< tType > & operator=(cl_3dPoint< tType > const & point_1);};template < typename tType >// here cl_3dPoint is a generic template, not a type.  Each occurance of cl_3dPoint must// have a valid template parameter to resolve it as a type.  The following line is therefore// incorrect because of the return typecl_3dPoint & cl_3dPoint< tType >::operator=(cl_3dPoint< tType > const & point_1)// the following line is the corrected formcl_3dPoint< tType > & cl_3dPoint< tType >::operator=(cl_3dPoint< tType > const & point_1){	if (this != &point_1)	{		this->x = point_1.x;		this->y = point_1.y;		this->z = point_1.z;	}	return *this;}


Enigma
i don t want to start a seperate thread so i ll just post it here.


i have encountered a strangeness with MSVC++6.0

i have a header and source file

but msvc++ doesn t allow me to move the implementation of memberfunctions out of its declaration header file

i think you can do this with gcc


is there a fix for this?
http://www.8ung.at/basiror/theironcross.html
Quote:Original post by Basiror
i don t want to start a seperate thread so i ll just post it here.


That's called thread hijacking <_<. MSVC++6.0 smells bad and has bad template support. That said, it should let you move out member functions just fine, as long as they are not both templated and placed in a source file (which virtually no compilers support at least by default settings).

As with many problems, it would be best to start a new thread with a minimal, working example of the problem you are experiencing, along with any errors (be it the description of crashes or a full copy/paste of compiler errors/warnings generated) encountered.

Without this information, your question is just about as vauge as "Can I fix that part in my car next to the thing?"

This topic is closed to new replies.

Advertisement