Trouble with operator overloading/type conversion

Discussion in 'C++' started by Philip Pemberton, Oct 24, 2004.

  1. Hi,
    I've just been trying to get some (pretty badly written) code working
    on a different compiler. Unfortunately, I've hit a problem. When the
    code below is compiled under Borland C++ it (allegedly) works fine. If I
    try and compile it with GNU G++, I get the following error report:

    bug.cpp: In function `GF2Poly operator%(OddGF2Poly&, OddGF2Poly&)':
    bug.cpp:21: call of overloaded `GF2Poly(OddGF2Poly&)' is ambiguous
    bug.cpp:3: candidates are: GF2Poly::GF2Poly(const GF2Poly&)
    bug.cpp:7: GF2Poly::GF2Poly(long unsigned int = 0)

    Could someone please tell me what's going wrong and how I could fix the
    problem and get this code to compile (and, preferably, run)? This is a
    severely trimmed down version of the code I'm trying to get working.

    --- CODE BEGINS
    typedef unsigned long UL;

    class GF2Poly {
    public:
    UL p;

    GF2Poly(UL x = 0) { p = x; }
    operator UL() { return (p); }
    };

    class OddGF2Poly {
    public:
    UL p;

    operator UL() { return (p); }
    operator GF2Poly() { return GF2Poly((p << 1) | 1); }
    };

    GF2Poly operator% (OddGF2Poly &xx, OddGF2Poly &yy)
    {
    return GF2Poly(yy);
    }

    int main(void) {
    GF2Poly gfp;
    OddGF2Poly ogp1, ogp2;

    gfp = ogp1 % ogp2;
    return 0;
    }
    --- CODE ENDS

    Thanks,
    Phil.
    (valid address)
    http://www.philpem.me.uk/
    Philip Pemberton, Oct 24, 2004
    #1
    1. Advertising

  2. Philip Pemberton wrote:
    ....
    > Could someone please tell me what's going wrong and how I could fix the
    > problem and get this code to compile (and, preferably, run)? This is a
    > severely trimmed down version of the code I'm trying to get working.
    >
    > --- CODE BEGINS
    > typedef unsigned long UL;
    >
    > class GF2Poly {
    > public:
    > UL p;
    >


    Note that the compiler provides:

    GF2Poly(const GF2Poly &)

    > GF2Poly(UL x = 0) { p = x; }
    > operator UL() { return (p); }
    > };
    >
    > class OddGF2Poly {
    > public:
    > UL p;
    >
    > operator UL() { return (p); }
    > operator GF2Poly() { return GF2Poly((p << 1) | 1); }


    The danger of conversion operators is that you can create multiple
    ambiguous conversions and hence you're required to specify them !

    > };
    >
    > GF2Poly operator% (OddGF2Poly &xx, OddGF2Poly &yy)
    > {
    > return GF2Poly(yy);


    Since you have 2 constructors (one that takes const GF2Poly & which
    matches with the operator GF2Poly(), and another that matches with
    operator UL(), the compiler can't choose (because the standard says so!).

    You can either.

    return GF2Poly(UL(yy));
    or
    return GF2Poly(yy.operator GF2Poly());

    Ask yourself if you can remove the operators T() functions ...

    At a guess, I would remove the operator UL() methods because it would be
    much safer to use a method like:

    UL Order()
    {
    return p;
    }

    .... and there would be no ambiguity.

    > }
    >
    > int main(void) {
    > GF2Poly gfp;
    > OddGF2Poly ogp1, ogp2;
    >
    > gfp = ogp1 % ogp2;
    > return 0;
    > }
    > --- CODE ENDS



    BTW - good job on the code snippet !
    Gianni Mariani, Oct 24, 2004
    #2
    1. Advertising

  3. "Philip Pemberton" <> wrote...
    > Hi,
    > I've just been trying to get some (pretty badly written) code working on
    > a different compiler. Unfortunately, I've hit a problem. When the code
    > below is compiled under Borland C++ it (allegedly) works fine. If I try
    > and compile it with GNU G++, I get the following error report:
    >
    > bug.cpp: In function `GF2Poly operator%(OddGF2Poly&, OddGF2Poly&)':
    > bug.cpp:21: call of overloaded `GF2Poly(OddGF2Poly&)' is ambiguous
    > bug.cpp:3: candidates are: GF2Poly::GF2Poly(const GF2Poly&)
    > bug.cpp:7: GF2Poly::GF2Poly(long unsigned int = 0)
    >
    > Could someone please tell me what's going wrong and how I could fix the
    > problem and get this code to compile (and, preferably, run)? This is a
    > severely trimmed down version of the code I'm trying to get working.


    The error comes from the attemps of the compiler to find a suitable
    conversion from 'OddGF2Poly&' argument (yy) in order to create a GF2Poly.
    Since the "functional type conversion" is used, the compiler probably
    tries to consider only conversion by constructor as possible. The fix
    is simple. See below.


    >
    > --- CODE BEGINS
    > typedef unsigned long UL;
    >
    > class GF2Poly {
    > public:
    > UL p;
    >
    > GF2Poly(UL x = 0) { p = x; }
    > operator UL() { return (p); }
    > };
    >
    > class OddGF2Poly {
    > public:
    > UL p;
    >
    > operator UL() { return (p); }
    > operator GF2Poly() { return GF2Poly((p << 1) | 1); }
    > };
    >
    > GF2Poly operator% (OddGF2Poly &xx, OddGF2Poly &yy)
    > {
    > return GF2Poly(yy);


    Just drop the 'GF2Poly' making it

    return yy;

    > }
    >
    > int main(void) {
    > GF2Poly gfp;
    > OddGF2Poly ogp1, ogp2;
    >
    > gfp = ogp1 % ogp2;
    > return 0;
    > }
    > --- CODE ENDS
    >
    > Thanks,
    > Phil.
    > (valid address)
    > http://www.philpem.me.uk/
    Victor Bazarov, Oct 24, 2004
    #3
  4. Philip Pemberton

    DaKoadMunky Guest


    >Just drop the 'GF2Poly' making it
    >
    > return yy;


    I am not familiar with "functional type conversion." I found no references to
    it and C++ using Google.

    Could you elaborate?

    Doesn't the compiler still have the choice of two equally good conversions
    available when constructing the return value?

    This modified example still did not compile using VC++.NET. It said the call
    to the GF2Poly ctor was ambiguous.
    DaKoadMunky, Oct 24, 2004
    #4
  5. DaKoadMunky wrote:
    >>Just drop the 'GF2Poly' making it
    >>
    >> return yy;

    >
    >
    > I am not familiar with "functional type conversion." I found no references to
    > it and C++ using Google.


    C++ has a "conversion" operator facility that allows you to provide a
    conversion function based on the type of the value being assigned.

    i.e.

    struct Y;
    struct X{
    operator Y(); // conversion function to convert an X to a Y
    };

    The problem you have is that it can introduce multiple ambiguous ways to
    convert and the standard says that if there exists ambiguity, it is an
    error.

    >
    > Could you elaborate?
    >
    > Doesn't the compiler still have the choice of two equally good conversions
    > available when constructing the return value?


    2 equally good conversions is an error according to the standard.

    >
    > This modified example still did not compile using VC++.NET. It said the call
    > to the GF2Poly ctor was ambiguous.


    See my response to the OP.
    Gianni Mariani, Oct 24, 2004
    #5
  6. Philip Pemberton

    DaKoadMunky Guest

    >This modified example still did not compile using VC++.NET. It said the call
    >to the GF2Poly ctor was ambiguous.


    I am quoting myself! Never done that before.

    The Comeau Online Compiler accepted Victors modification.

    That doesn't make it legal of course, but I generally assume that Comeau
    implements the standard correctly.

    So how is it that the change eliminates the ambiguity?

    Also, I was thinking the original example contained two implicit conversion
    sequences in one case and that it would select the path that contained only one
    implicit conversion.

    One possibility for the original example was...

    OddGF2Poly - > int via OddGF2Poly::eek:perator int()
    then
    int -> GF2Poly via GF2Poly(int)

    I thought only one conversion could be applied to make a call succeed.

    How am I mistaken here?
    DaKoadMunky, Oct 24, 2004
    #6
    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. John Smith
    Replies:
    2
    Views:
    415
    Ivan Vecerina
    Oct 6, 2004
  2. 2simple
    Replies:
    1
    Views:
    2,127
    2simple
    Oct 19, 2006
  3. hurcan solter
    Replies:
    3
    Views:
    716
    Cholo Lennon
    Aug 29, 2007
  4. Martin T.
    Replies:
    7
    Views:
    808
    Martin T.
    Mar 10, 2008
  5. Replies:
    6
    Views:
    663
    James Kanze
    May 15, 2009
Loading...

Share This Page