VC++: Cast operator not used?

Discussion in 'C++' started by A. W. Dunstan, Feb 21, 2005.

  1. 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;
    };
    A. W. Dunstan, Feb 21, 2005
    #1
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. danny van elsen
    Replies:
    6
    Views:
    3,709
    Pete Becker
    May 7, 2005
  2. MSG

    to cast or not to cast malloc ?

    MSG, Feb 6, 2004, in forum: C Programming
    Replies:
    38
    Views:
    1,075
    Dan Pop
    Feb 10, 2004
  3. EvilRix
    Replies:
    8
    Views:
    640
    Martin Dickopp
    Feb 14, 2004
  4. John Goche
    Replies:
    2
    Views:
    343
    Frederick Gotham
    Sep 4, 2006
  5. Pavel
    Replies:
    7
    Views:
    527
    Pavel
    Sep 19, 2010
Loading...

Share This Page