Sign in to follow this  
vengeanceis

Mingw C++: template friend operator screwup

Recommended Posts

I use Dev-C++ 5.0 beta 9 (4.9.9.0) and Mingw/GCC 3.3.1 that comes in the package. I've got a project that compiles under MSVC++, and which causes a wierd error while trying to compile with Mingw:
Quote:
// .......................................... typedef short unsigned int USHORT; template <typename TDATA=double,typename TCOUNT=USHORT> class A { void* _ta; TCOUNT& _size_field() { return ((TCOUNT*)_ta)[0]; } TCOUNT& _count_field() { return ((TCOUNT*)_ta)[1]; } TDATA* _data_ptr() { return (TDATA*)((TCOUNT*)_ta + 2); } void _release(); // releases data structure public: alloc(n); // allocates data structure of size n (n*TDATA + 2*TCOUNT bytes) A(void) { _ta = NULL; } A(TCOUNT n, TDATA* pdata); A(A& ta0); A& operator=(A& ta0); A operator*(TDATA d); }; template <typename TDATA,typename TCOUNT> A<TDATA,TCOUNT>::A(A<TDATA,TCOUNT>& ta0) { _ta = ta0._ta; if (ta0._ta!=NULL) ta0._count_field()++; } template <typename TDATA,typename TCOUNT> A<TDATA,TCOUNT>::A(TCOUNT n, TDATA* pdata) { _ta = NULL; if ( alloc(n)==n ) memcpy( _data_ptr(), pdata, n*sizeof(TDATA) ); } template <typename TDATA,typename TCOUNT> A<TDATA,TCOUNT>& A<TDATA,TCOUNT>::operator=(A<TDATA,TCOUNT>& ta0) { if ( ta0._ta!=NULL ) ta0._count_field()++; // increse target's ref count _release(); // releases current data struct _ta = ta0._ta; // and hang onto the new guy return *this; } template <typename TDATA,typename TCOUNT> A<TDATA,TCOUNT> A<TDATA,TCOUNT>::operator*(TDATA d) { A<TDATA,TCOUNT> ta_RESULT; TCOUNT len = size(); if ( len<=0 ) return ta_RESULT; if (ta_RESULT.alloc(len)!=len) return ta_RESULT; TDATA* pRESULT = ta_RESULT._data_ptr(); TDATA* pdata_source = data_ptr(); for (register TCOUNT j=0; j<len; j++) pRESULT[j] = pdata_source[j] * d; return ta_RESULT; } main() { A<> ta_X(Xdim, 0.3, 0.3, 0.3); A<> ta_Y(Ydim, 0.6, 0.2, 0.3); double d = 3.0; ta_Y = ta_X * d; // <- ERROR IN ASSIGNMENT } // ..................................................
GIVES THE ERROR: main.cpp:: error: no match for 'operator=' in 'ta_Y = operator*(A<TDATA, TCOUNT>&, TDATA) [with TDATA = double, TCOUNT = USHORT](d)' trivialarray.h:293: error: candidates are: A<TDATA, TCOUNT>& A<TDATA, TCOUNT>::operator=(A<TDATA, TCOUNT>&) [with TDATA = double, TCOUNT = USHORT] trivialarray.h:310: error: A<TDATA, TCOUNT>& A<TDATA, TCOUNT>::operator=(TDATA) [with TDATA = double, TCOUNT = USHORT] This is some problem with non-member template functions in Mingw. There is another post on the same issue: http://gcc.gnu.org/ml/gcc/2004-08/msg01321.html Can anyone EXPLAIN what the heck the problem is? [Edited by - vengeanceis on November 9, 2004 4:15:22 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by Jingo
The problem is likely that you cannot bind a non-const reference to an r-value. Change the operator= parameter to a const reference.


Jingo, you are genius!

The only thing is.. look: i changed operator= to
Quote:
CTrivialArray& operator=(const CTrivialArray& ta0);

but if you look at the code, it calls
Quote:
ta0._count_field()++;

which I have to change to const too:
Quote:
TCOUNT& _count_field() const { return ((TCOUNT*)_ta)[1]; });


which is.. not really .. beautiful, because the _count_field()++ DOES modify the object.. (not the object itself, but the data structure it points to, actually)..
so, it's not quite good to call the _count_field() private method "const".

can suggest a workaround? or just lie on conscience
though it compiles and runs fine now.

Share this post


Link to post
Share on other sites
Quote:
Original post by vengeanceis
which is.. not really .. beautiful, because the _count_field()++ DOES modify the object.. (not the object itself, but the data structure it points to, actually)..
so, it's not quite good to call the _count_field() private method "const".


IMHO, this is OK. Besides the fact that technically it's not really modifying the object (it's modifying something that the object has a pointer to), there is a keyword for supporting "const" functions that modify internal variables:

class ireferencecountedobjectinterfacewitharidiculouslylongname
{
mutable int reference_count;
public:
void reference( void ) const { ++reference_count; }
void dereference( void ) const { --reference_count; }
};


The idea is that calling the const functions dosn't change the outward apparent behavior of the class, but rather maintains "behind the scenes" information. No normal class needs to worry about the reference count of an object.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this