Automatic conversion operators

Discussion in 'C++' started by Tom Smith, Nov 1, 2006.

  1. Tom Smith

    Tom Smith Guest

    Hi,

    What I want to do is rather complicated to describe but simple to demonstrate:
    so I'll do that instead.

    The following doesn't compile. Is there a a way to make it work? (by "make it
    work", I mean: can I write the classes A, B and C in such a way that the given
    main function will compile and do what I expect).

    Cheers,


    Tom



    #include <iostream>

    using namespace std;

    class A
    {
    void function() { cout << "function called!"; }
    };

    class B
    {
    };

    class C
    {
    operator A& () { return a; }
    operator B& () { return b; }
    A a;
    B b;
    };

    int main()
    {
    C c;
    c.function(); // I'd like this to automatically convert C to an A
    }
    Tom Smith, Nov 1, 2006
    #1
    1. Advertising

  2. Tom Smith

    Salt_Peter Guest

    Tom Smith wrote:
    > Hi,
    >
    > What I want to do is rather complicated to describe but simple to demonstrate:
    > so I'll do that instead.
    >
    > The following doesn't compile. Is there a a way to make it work? (by "make it
    > work", I mean: can I write the classes A, B and C in such a way that the given
    > main function will compile and do what I expect).
    >
    > Cheers,
    >
    >
    > Tom
    >
    >
    >
    > #include <iostream>
    >
    > using namespace std;
    >
    > class A
    > {
    > void function() { cout << "function called!"; }
    > };
    >
    > class B
    > {
    > };
    >
    > class C
    > {
    > operator A& () { return a; }
    > operator B& () { return b; }
    > A a;
    > B b;
    > };
    >
    > int main()
    > {
    > C c;
    > c.function(); // I'd like this to automatically convert C to an A
    > }


    In what way does:

    class C
    {
    A a;
    B b;
    public:
    void function() { a.function(); }
    };

    not get you what you want?
    Salt_Peter, Nov 1, 2006
    #2
    1. Advertising

  3. Tom Smith

    Salt_Peter Guest

    Salt_Peter wrote:
    > Tom Smith wrote:
    > > Hi,
    > >
    > > What I want to do is rather complicated to describe but simple to demonstrate:
    > > so I'll do that instead.
    > >
    > > The following doesn't compile. Is there a a way to make it work? (by "make it
    > > work", I mean: can I write the classes A, B and C in such a way that the given
    > > main function will compile and do what I expect).
    > >
    > > Cheers,
    > >
    > >
    > > Tom
    > >
    > >
    > >
    > > #include <iostream>
    > >
    > > using namespace std;
    > >
    > > class A
    > > {
    > > void function() { cout << "function called!"; }
    > > };
    > >
    > > class B
    > > {
    > > };
    > >
    > > class C
    > > {
    > > operator A& () { return a; }
    > > operator B& () { return b; }
    > > A a;
    > > B b;
    > > };
    > >
    > > int main()
    > > {
    > > C c;
    > > c.function(); // I'd like this to automatically convert C to an A
    > > }

    >
    > In what way does:
    >
    > class C
    > {
    > A a;
    > B b;
    > public:
    > void function() { a.function(); }
    > };
    >
    > not get you what you want?


    And since you did say "convert" a C to an A:

    class C : public A
    {
    B b;
    };
    Salt_Peter, Nov 1, 2006
    #3
  4. Tom Smith

    Salt_Peter Guest

    Salt_Peter wrote:
    > Tom Smith wrote:
    > > Hi,
    > >
    > > What I want to do is rather complicated to describe but simple to demonstrate:
    > > so I'll do that instead.
    > >
    > > The following doesn't compile. Is there a a way to make it work? (by "make it
    > > work", I mean: can I write the classes A, B and C in such a way that the given
    > > main function will compile and do what I expect).
    > >
    > > Cheers,
    > >
    > >
    > > Tom
    > >
    > >
    > >
    > > #include <iostream>
    > >
    > > using namespace std;
    > >
    > > class A
    > > {
    > > void function() { cout << "function called!"; }
    > > };
    > >
    > > class B
    > > {
    > > };
    > >
    > > class C
    > > {
    > > operator A& () { return a; }
    > > operator B& () { return b; }
    > > A a;
    > > B b;
    > > };
    > >
    > > int main()
    > > {
    > > C c;
    > > c.function(); // I'd like this to automatically convert C to an A
    > > }

    >
    > In what way does:
    >
    > class C
    > {
    > A a;
    > B b;
    > public:
    > void function() { a.function(); }
    > };
    >
    > not get you what you want?


    And since you did say "convert" a C to an A:

    class C : public A
    {
    B b;
    };
    Salt_Peter, Nov 1, 2006
    #4
  5. Tom Smith

    Tom Smith Guest

    Salt_Peter wrote:
    > Salt_Peter wrote:
    >> Tom Smith wrote:
    >>> Hi,
    >>>
    >>> What I want to do is rather complicated to describe but simple to demonstrate:
    >>> so I'll do that instead.
    >>>
    >>> The following doesn't compile. Is there a a way to make it work? (by "make it
    >>> work", I mean: can I write the classes A, B and C in such a way that the given
    >>> main function will compile and do what I expect).
    >>>
    >>> Cheers,
    >>>
    >>>
    >>> Tom
    >>>
    >>>
    >>>
    >>> #include <iostream>
    >>>
    >>> using namespace std;
    >>>
    >>> class A
    >>> {
    >>> void function() { cout << "function called!"; }
    >>> };
    >>>
    >>> class B
    >>> {
    >>> };
    >>>
    >>> class C
    >>> {
    >>> operator A& () { return a; }
    >>> operator B& () { return b; }
    >>> A a;
    >>> B b;
    >>> };
    >>>
    >>> int main()
    >>> {
    >>> C c;
    >>> c.function(); // I'd like this to automatically convert C to an A
    >>> }

    >> In what way does:
    >>
    >> class C
    >> {
    >> A a;
    >> B b;
    >> public:
    >> void function() { a.function(); }
    >> };
    >>
    >> not get you what you want?

    >




    You're right - I could do that. But this is a very simplified example: what i
    want is actually a great deal more complicated, but this syntactic sugar is what
    would make it about a thousand times easier; and the implementation problem in
    my real program is identical to the one in the toy example above. ("Post minimal
    code that demonstrates your problem", remember?)

    Tom
    Tom Smith, Nov 1, 2006
    #5
  6. Tom Smith wrote:
    > Salt_Peter wrote:
    >> Salt_Peter wrote:
    >>> Tom Smith wrote:
    >>>> Hi,
    >>>>
    >>>> What I want to do is rather complicated to describe but simple to
    >>>> demonstrate: so I'll do that instead.
    >>>>
    >>>> The following doesn't compile. Is there a a way to make it work?
    >>>> (by "make it work", I mean: can I write the classes A, B and C in
    >>>> such a way that the given main function will compile and do what I
    >>>> expect). Cheers,
    >>>>
    >>>>
    >>>> Tom
    >>>>
    >>>>
    >>>>
    >>>> #include <iostream>
    >>>>
    >>>> using namespace std;
    >>>>
    >>>> class A
    >>>> {
    >>>> void function() { cout << "function called!"; }
    >>>> };
    >>>>
    >>>> class B
    >>>> {
    >>>> };
    >>>>
    >>>> class C
    >>>> {
    >>>> operator A& () { return a; }
    >>>> operator B& () { return b; }
    >>>> A a;
    >>>> B b;
    >>>> };
    >>>>
    >>>> int main()
    >>>> {
    >>>> C c;
    >>>> c.function(); // I'd like this to automatically convert C to an
    >>>> A }
    >>> [...]

    > this is a very simplified
    > example: what i want is actually a great deal more complicated, but
    > this syntactic sugar is what would make it about a thousand times
    > easier; and the implementation problem in my real program is
    > identical to the one in the toy example above. ("Post minimal code
    > that demonstrates your problem", remember?)


    I do not think it is possible. The compiler is not obligated (by the
    Standard) to look for those conversions. It is similar to this:

    struct A {
    A(int) {}
    void operator+(A const&) {}
    };

    int main() {
    A a(42);
    666 + a; // won't compile
    }

    The compiler does not have to look for an existing conversion from
    '666' to 'A' just to resolve the operator+ when operator+ is a member.
    For non-members it would do it. In your case the '.' operator is the
    connection (like the '+' in my example). The left-hand side will not
    be converted just to satisfy the need to find the 'membership' for
    'function' expression (the right-hand side).

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Nov 1, 2006
    #6
  7. Tom Smith

    Tom Smith Guest

    Victor Bazarov wrote:
    > Tom Smith wrote:
    >> Salt_Peter wrote:
    >>> Salt_Peter wrote:
    >>>> Tom Smith wrote:


    <snip>
    >>>>> The following doesn't compile. Is there a a way to make it work?

    <snip>

    >>>>> #include <iostream>
    >>>>>
    >>>>> using namespace std;
    >>>>>
    >>>>> class A
    >>>>> {
    >>>>> void function() { cout << "function called!"; }
    >>>>> };
    >>>>>
    >>>>> class B
    >>>>> {
    >>>>> };
    >>>>>
    >>>>> class C
    >>>>> {
    >>>>> operator A& () { return a; }
    >>>>> operator B& () { return b; }
    >>>>> A a;
    >>>>> B b;
    >>>>> };
    >>>>>
    >>>>> int main()
    >>>>> {
    >>>>> C c;
    >>>>> c.function(); // I'd like this to automatically convert C to an
    >>>>> A }
    >>>> [...]


    <snip>

    >
    > I do not think it is possible. The compiler is not obligated (by the
    > Standard) to look for those conversions.


    This is what I thought.


    It is similar to this:
    >
    > struct A {
    > A(int) {}
    > void operator+(A const&) {}
    > };
    >
    > int main() {
    > A a(42);
    > 666 + a; // won't compile
    > }
    >


    This is in fact closer to (part of) my actual problem: two classes A and B which
    both auto-convert to int, and for which it would be nice to simply write a+b etc
    instead of having to write specific operators or explicitly converting.

    > The compiler does not have to look for an existing conversion from
    > '666' to 'A' just to resolve the operator+ when operator+ is a member.
    > For non-members it would do it. In your case the '.' operator is the
    > connection (like the '+' in my example). The left-hand side will not
    > be converted just to satisfy the need to find the 'membership' for
    > 'function' expression (the right-hand side).


    Ok. Do you have any idea what the neatest way would be to do this sort of thing?

    Thanks again,



    Tom
    Tom Smith, Nov 1, 2006
    #7
  8. Tom Smith wrote:
    > [..]
    > Ok. Do you have any idea what the neatest way would be to do this
    > sort of thing?


    Well, with operators it is solved simply: the operator needs to be
    defined a non-member:

    struct A {
    A(int) {}
    };

    void operator+(A const&, A const&) {}

    int main() {
    A a(42);
    666 + a; // compiles nicely
    }

    Now, I don't know your "real" problem, but if it gives you an idea,
    good. If it doesn't, you will have to post more information.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Nov 1, 2006
    #8
  9. Tom Smith

    Rolf Magnus Guest

    Victor Bazarov wrote:

    > Tom Smith wrote:
    >> [..]
    >> Ok. Do you have any idea what the neatest way would be to do this
    >> sort of thing?

    >
    > Well, with operators it is solved simply: the operator needs to be
    > defined a non-member:
    >
    > struct A {
    > A(int) {}
    > };
    >
    > void operator+(A const&, A const&) {}
    >
    > int main() {
    > A a(42);
    > 666 + a; // compiles nicely
    > }


    That doesn't look like what the OP wants. I think that he wants that in:

    int main()
    {
    A a(42);
    A b(4711);
    a + b;
    }

    a and b are both implicitly converted to int and then the operator+ for int
    is used, so that he doesn't need to define his own operator+ at all. I
    guess the idea is that he doesn't want to implement dozens of operators to
    make the class behave similar to int. However, I don't think that's
    possible.
    Rolf Magnus, Nov 2, 2006
    #9
    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. Guest
    Replies:
    1
    Views:
    739
    Guest
    Jun 29, 2004
  2. Eric
    Replies:
    1
    Views:
    304
    Rob Williscroft
    Nov 22, 2003
  3. Replies:
    3
    Views:
    4,314
  4. rasbury
    Replies:
    2
    Views:
    425
    David Hilsee
    Feb 13, 2005
  5. Russ
    Replies:
    3
    Views:
    288
    Dan Bishop
    Jul 27, 2007
Loading...

Share This Page