CArray changes in VC 2003 vs VC 6.0

D

danip

Hi,
I used to have the following:
class CArchive
{
public:
// create and specify the filename to use
CArchive(CString filename, DWORD size);
virtual ~CArchive();

CArchive& operator<<(bool b);
CArchive& operator<<(BYTE by);
CArchive& operator<<(WORD w);
CArchive& operator<<(LONG l);
CArchive& operator<<(DWORD dw);
CArchive& operator<<(float f);
CArchive& operator<<(double d);
CArchive& operator<<(int i);
CArchive& operator<<(short w);
CArchive& operator<<(char ch);
CArchive& operator<<(unsigned u);
CArchive& operator<<(const CString& s);

};

//template function to write array to the archive
template <class ARCHIVE, class ARRAY>
ARCHIVE& ArchiveAddArray(ARCHIVE& archive, const ARRAY& array)
{
int nSize = array.GetSize();
archive << nSize;
for(int n=0; n< nSize; n++)
{
archive << array[n];
}

return archive;
}

struct BBLStruct
{
CString m_str1;
CString m_str2;
CString m_str3;
};

class CBBLstructArray : public CArray<BBLStruct, BBLStruct&>
{
};


class CArchiveEx : public CArchive
{
public:
CArchiveEx(CString filename, DWORD size)
: CArchive(filename, size) {}
virtual ~CArchiveEx() {}

CArchiveEx& operator<<(CBBLstructArray& BBLs)
{ return ArchiveExAddArray(*this,BBLs); }
};

template <class ARRAY>
CArchiveEx& ArchiveExAddArray(CArchiveEx& self, const ARRAY& array)
{
ArchiveAddArray(self, array);
return self;
}

in VC++ 6.0 and everything worked okay.

I'm now moving to VC 7.1 and I receive the following error:
error C2678: binary '<<' : no operator found which takes a left-hand
operand of type 'CArchiveEx' (or there is no acceptable conversion)

When I delete the method:
CArchiveEx& operator<<(CBBLstructArray& BBLs)
{ return ArchiveExAddArray(*this,BBLs); }

everything is okay.

What changed in templates in VC 7.1 ? and solutions ?

Thanks

-- Dani
 
H

Holger Grund

danip said:
I used to have the following:
class CArchive
{
public: [..]
CArchive& operator<<(bool b);
CArchive& operator<<(BYTE by); [..]
[..]

class CArchiveEx : public CArchive
{
public: [..]
CArchiveEx& operator<<(CBBLstructArray& BBLs)
{ return ArchiveExAddArray(*this,BBLs); }
};
This declarations hides all other operator<< from CArchive.
You can use a using declarations to reintroduce them into
the derived class scope.

using CArchive::blush:perator<<;
I'm now moving to VC 7.1 and I receive the following error:
error C2678: binary '<<' : no operator found which takes a left-hand
operand of type 'CArchiveEx' (or there is no acceptable conversion)
You should always look at the full error message. The IDE Error/Task
List window doesn't show it all. It would also help if you posted
the exact location where the error occurs.
When I delete the method:
CArchiveEx& operator<<(CBBLstructArray& BBLs)
{ return ArchiveExAddArray(*this,BBLs); }

everything is okay.
You probably want some of the base class operator<<,
which is not found by standard name lookup rules.

-hg
 
D

danip

The error is:
error C2678: binary '<<' : no operator found which takes a left-hand
operand of type 'CArchiveEx' (or there is no acceptable conversion)
ArchiveEx.h(38) : see reference to function template
instantiation 'ARCHIVE &ArchiveExAddArray<CArchiveEx,ARRAY>(ARCHIVE
&,const ARRAY &)' being compiled
with
[
ARCHIVE=CArchiveEx,
ARRAY=CBBLstructArray
]
ArchiveEx.h(92) : see reference to function template
instantiation 'CArchiveEx
&ArchiveExAddArray<CArchiveEx,ARRAY>(CArchiveEx &,const ARRAY &)' being
compiled
with
[
ARRAY=CDevDBKDCstructArray
]



Let me ntify the CArchive is my own class and not the MFC one.
 
D

danip

The full error is:
error C2678: binary '<<' : no operator found which takes a left-hand
operand of type 'CArchiveEx' (or there is no acceptable conversion)
ArchiveEx.h(38) : see reference to function template
instantiation 'ARCHIVE &ArchiveExAddArray<CArchiveEx,ARRAY>(ARCHIVE
&,const ARRAY &)' being compiled
with
[
ARCHIVE=CArchiveEx,
ARRAY=CBBLstructArray
]
ArchiveEx.h(92) : see reference to function template
instantiation 'CArchiveEx
&ArchiveExAddArray<CArchiveEx,ARRAY>(CArchiveEx &,const ARRAY &)' being
compiled
with
[
ARRAY=CBBLstructArray
]


Let me notify that the CArchive is mine and not the MFC.
 
H

Holger Grund

danip said:
The full error is:
error C2678: binary '<<' : no operator found which takes a left-hand
operand of type 'CArchiveEx' (or there is no acceptable conversion)
ArchiveEx.h(38) : see reference to function template
instantiation 'ARCHIVE &ArchiveExAddArray<CArchiveEx,ARRAY>(ARCHIVE
Are you sure that this is the correct message?
It would make sense if it was ArchiveAddArray (no Ex).

This function uses
archive << nSize; // this should error

left hand type is CArchiveEx, right hand is int.

Your operator<< in CArchiveEx hides the CArchive::blush:perator<<
overloads.
It should work if look up would be done in CArchive (e.g.)
static_cast<CArchive&>(archive) << nSize;

But what you really want in this case, is introducing the
operator<< overloads into the derived class, so that the
compiler will automatically chose the correct one.

To do so add a using declaration, into the CArchiveEx
class declaration like:
class CArchiveEx ... { ..
public:
using CArchive::blush:perator<<;
....
};

Apparently, this is a standard conformance improvement
in VC 7.1 over VC6 bad name lookup.

-hg
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top