By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,889 Members | 1,373 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,889 IT Pros & Developers. It's quick & easy.

VC++: Cast operator not used?

P: n/a
I'm porting some code to Visual C++ and have run into a problem - the
compiler won't use a user-written cast operator.

The code uses an envelope-letter approach to passing (potentially)
large pieces of data around, and requires that certain methods return
an Envelope with a specific kind of Letter as it's content. I have a
cast operator that converts from what I've got to what should be
returned, but it seems that the compiler only looks at constructors
for the return type.

The code works fine with the SGI MIPSPRO and Linux GCC compilers.
With MS Visual C++ .NET (v. 7.1.3008) it says:

CDP3x3LinearTransform.c++(196): error C2668: 'DataPacket::DataPacket' :
ambiguous call to overloaded function
DataPacket.h(53): could be 'DataPacket::DataPacket(Letter &)'
DataPacket.h(52): or 'DataPacket::DataPacket(const DataPacket &)'
DataPacket.h(51): or 'DataPacket::DataPacket(const Envelope<T> &)'
where the offending line in CDP3x3LinearTransform.c++ looks like this:

DataPacket
CDP3x3LinearTransform::Output() const {
ChannelDataPacket result;
//... compute result here...
return result; // line 196
}

In this case I've got a ChannelDataPacket and need to return a
DataPacket. ChannelDataPacket is NOT derived from DataPacket (even
tho' you'd expect that, given their names), but they ARE related.
ChannelDataPacket DOES have a conversion operator to convert itself to
a DataPacket, however (see below). I've found two work-arounds:

#1: Call the cast operator explicitly:

return result.operator omiDataPacket();

#2: Explicitly cause the cast operator to be called by adding code:

DataPacket dp;
dp = result;
return dp;

I have two objections to both of these workarounds: a) If it won't
work as written, what's the point in having a cast operator? and b)
This is done in about 150 different places in 70 different classes.
That's just way too much typing for someone as lazy as I am.
Questions:

- Is this a known problem with VC++? I've looked in the MS knowledge
base and found nothing, but I might be looking for the wrong thing.

- Is there some way of getting the VC++ compiler to notice (and use)
the cast operator without having to inflict a MS-specific kludge all
over the code?
Thanks!
Code:

//---------------------------------------------
// The Envelope to be wrapped around a Letter.
//---------------------------------------------
class EnvelopeBase
{
public:
virtual ~EnvelopeBase();
EnvelopeBase();
EnvelopeBase(Letter::WriteAndCopyModeType wcm);
EnvelopeBase(const EnvelopeBase& from);
EnvelopeBase& operator=(const EnvelopeBase& rhs);
};
template < class T >
class Envelope : public EnvelopeBase
{
public:
virtual ~Envelope();
Envelope();
Envelope( const Envelope& );
Envelope( Letter& letter );

Envelope& operator=( const Envelope& );
T* operator->();
const T* operator->() const;
};

//---------------------------------------------
// Letter - What gets put inside an Envelope.
//---------------------------------------------
class Letter
{
public:
enum WriteAndCopyModeType { ValueImmediate, ValueDelayed,
Pointer };
enum ExemplarType { exemplar };
virtual ~Letter();
Letter();
Letter( const String& );
Letter( const Letter& );

protected:
friend class Envelope< Letter >;
};
//---------------------------------------------
// DataPacketLetter - the data we're interested in.
//---------------------------------------------
class DataPacketLetter : public Letter
{
public:
virtual ~DataPacketLetter();
DataPacketLetter();
DataPacketLetter( const DataPacketLetter& );
DataPacketLetter( ExemplarType );
DataPacketLetter( const String& );

protected:
DataPacketLetter( const String&, ExemplarType );
};
//---------------------------------------------
// DataPacket - the data we're interested in, wrapped in an Envelope.
//---------------------------------------------
class DataPacket : public Envelope< DataPacketLetter >
{
public:
virtual ~DataPacket();
DataPacket();
DataPacket( const Envelope< DataPacketLetter >& from );
DataPacket( const DataPacket& from );
DataPacket( Letter& letter );
DataPacket& operator=( const DataPacket& rhs );
operator DataPacketLetter&() const;
};


//---------------------------------------------
// ChannelDataPacket(Letter) - the data we're interested in, wrapped &
unwrapped.
//---------------------------------------------
class ChannelDataPacketLetter : public DataPacketLetter
{
public:
virtual ~ChannelDataPacketLetter();
ChannelDataPacketLetter();
ChannelDataPacketLetter( int theInitialSize );
ChannelDataPacketLetter( const ChannelDataPacketLetter& );
ChannelDataPacketLetter( ExemplarType );
ChannelDataPacketLetter( const String& );
};
class ChannelDataPacket : public Envelope< ChannelDataPacketLetter >
{
public:
virtual ~ChannelDataPacket();
ChannelDataPacket();
ChannelDataPacket( float theValue );
ChannelDataPacket( const ChannelDataPacket& theOriginal );
ChannelDataPacket( Letter& letter );
ChannelDataPacket& operator=( const ChannelDataPacket& theRhs );
ChannelDataPacket& operator=( const float& theRhs );
operator ChannelDataPacketLetter&() const;
operator DataPacket() const;
operator float() const;
};

Jul 23 '05 #1
Share this question for a faster answer!
Share on Google+

This discussion thread is closed

Replies have been disabled for this discussion.