overload resolution and conversion ops

Discussion in 'C++' started by xtrigger303@gmail.com, May 16, 2008.

  1. Guest

    Hi to all,
    I was reading Mr. Alexandrescu's mojo article and I've a hard time
    understanding the following.
    Let's suppose I have:

    //code
    struct A {};

    struct B : A {};

    struct C
    {
    operator A() const { return A(); }
    operator B() { return B(); }
    };

    void F( A const & ) {}
    void F( B const & ) {}

    C const H() { return C(); }

    int main()
    {
    F( C() ); // 1. called with a non-const rvalue
    F( H() ); // 2. called with a const rvalue
    }
    //end code

    I understand that if I have a const "C" (rvalue or lvalue, here it
    does not matter)
    the only option when calling "F" would be to use

    C::eek:perator A() const -> F( A const & )


    In the case I have a non-const "C" it seems that the compiler
    chooses

    C::eek:perator B() -> F( B const & )

    my understanding of the article is that this is because since
    B is derived from A, it's a better match than the base class.

    I do not understand then why the constness of operator A() makes
    the difference. If I remove it and make it just

    C::eek:perator A()

    my guess would be that that when calling "F" I would always get a call
    to
    F( B const & ). But instead the thing does not compile.

    My naive understanding then is that the constness of the conversion
    operators
    AND the fact the B is derived from A all come into play when
    "resolving" the call
    to "F". The problem is that I cannot fully understand the logic behind
    this nor
    I can find the right chapter in the standard. Tryed [over.ics.rank].
    Any help to understand this better would be greatly appreciated.

    Thanks in advance,
    Francesco
     
    , May 16, 2008
    #1
    1. Advertising

  2. James Kanze Guest

    On 16 mai, 14:24, wrote:
    > I was reading Mr. Alexandrescu's mojo article and I've a hard
    > time understanding the following.
    > Let's suppose I have:


    > //code
    > struct A {};


    > struct B : A {};


    > struct C
    > {
    > operator A() const { return A(); }
    > operator B() { return B(); }
    > };


    > void F( A const & ) {}
    > void F( B const & ) {}


    > C const H() { return C(); }


    > int main()
    > {
    > F( C() ); // 1. called with a non-const rvalue
    > F( H() ); // 2. called with a const rvalue}
    > }
    > //end code


    > I understand that if I have a const "C" (rvalue or lvalue,
    > here it does not matter) the only option when calling "F"
    > would be to use


    > C::eek:perator A() const -> F( A const & )


    Correct. The C::eek:perator B() conversion operator cannot be
    called (is not a viable function, in the words of the standard).

    > In the case I have a non-const "C" it seems that the compiler
    > chooses


    > C::eek:perator B() -> F( B const & )


    > my understanding of the article is that this is because since
    > B is derived from A, it's a better match than the base class.


    > I do not understand then why the constness of operator A()
    > makes the difference.


    It's rather the non-const-ness of operator B() that makes the
    difference. Because the operator is not const, it cannot be
    called on a const object.

    > If I remove it and make it just


    > C::eek:perator A()


    > my guess would be that that when calling "F" I would always
    > get a call to
    > F( B const & ). But instead the thing does not compile.


    If the object is const, only const functions can be called on
    it. If you remove const everywhere, then no functions can be
    called on the object. Whence your error.

    > My naive understanding then is that the constness of the
    > conversion operators AND the fact the B is derived from A all
    > come into play when "resolving" the call to "F".


    Sort of. Overload resolution doesn't consider functions which
    cannot be called because of a mismatch in the signatures. (It
    doesn't take things like access protection into consideration,
    so overload resolution can resolve to a private function which
    cannot be called.)

    > The problem is that I cannot fully understand the logic behind
    > this nor I can find the right chapter in the standard. Tryed
    > [over.ics.rank]. Any help to understand this better would be
    > greatly appreciated.


    You're not looking far enough. In the terms of the standard,
    overload resolution takes place in three steps: creating a list
    of candidate functions (results of name lookup and possibly
    template instantiations), creating a set of viable functions
    from the candidate functions (only those candidate functions
    whose signatures allow them to be called), and finally, choosing
    the best candidate function. In more usual terminology, only
    this last step would be considered "resolution", the first two
    steps only construct the set over which resolution is applied.
    But regardless of how they are called, all three steps take
    place, and the compiler will not consider a function that it
    doesn't find during name lookup (first step) or whose signature
    will not allow it to be called (second step).

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, May 16, 2008
    #2
    1. Advertising

  3. James Kanze Guest

    On 17 mai, 00:13, "Alf P. Steinbach" <> wrote:
    > * James Kanze:
    > > On 16 mai, 14:24, wrote:
    > >> I was reading Mr. Alexandrescu's mojo article and I've a hard
    > >> time understanding the following.
    > >> Let's suppose I have:


    > >> //code
    > >> struct A {};


    > >> struct B : A {};


    > >> struct C
    > >> {
    > >> operator A() const { return A(); }
    > >> operator B() { return B(); }
    > >> };


    > >> void F( A const & ) {}
    > >> void F( B const & ) {}


    > >> C const H() { return C(); }


    > >> int main()
    > >> {
    > >> F( C() ); // 1. called with a non-const rvalue
    > >> F( H() ); // 2. called with a const rvalue}
    > >> }
    > >> //end code


    > >> I understand that if I have a const "C" (rvalue or lvalue,
    > >> here it does not matter) the only option when calling "F"
    > >> would be to use


    > >> C::eek:perator A() const -> F( A const & )


    > > Correct. The C::eek:perator B() conversion operator cannot be
    > > called (is not a viable function, in the words of the
    > > standard).


    > Agreed.


    > >> In the case I have a non-const "C" it seems that the
    > >> compiler chooses


    > >> C::eek:perator B() -> F( B const & )


    > >> my understanding of the article is that this is because
    > >> since B is derived from A, it's a better match than the
    > >> base class.


    > >> I do not understand then why the constness of operator A()
    > >> makes the difference.


    > > It's rather the non-const-ness of operator B() that makes
    > > the difference. Because the operator is not const, it
    > > cannot be called on a const object.


    > But here you have overlooked the call 'F( C() )'.


    Not entirely, but I was mainly concerned with the call
    generating the error.

    > Remove the call 'F(H())' and the const on op B still makes a
    > difference... :)


    Well, it will certainly make a difference in some cases. The
    const-ness is part of the type, and will always play some role
    in overload resolution. As you say, I was mainly concerned with
    the F(H()).

    > OK, I don't understand this, even after scrutinizing the
    > standard, but I recognize that your explanation isn't it, that
    > it ignores the really relevant aspects.


    I know that as well. Overload resolution is one of the most
    complicated subjects in the standard, taking a full 15 pages of
    text, all of it relevant.

    > I should understand it, after all it's basic!


    Basically incomprehensible, you mean.

    It's saving grace is that it ends up doing what you intuitively
    would want, or generating an error (which can be eliminated by
    an explicit cast), so you can write robust C++ without
    understanding it.

    > , and I think I did understand it once, as one of the
    > volunteers helping Andrei with quality assurance on Mojo. But
    > darned if I now can get my head around this (same predicament
    > as the OP)!


    > >> If I remove it and make it just


    > >> C::eek:perator A()


    > >> my guess would be that that when calling "F" I would always
    > >> get a call to F( B const & ). But instead the thing does
    > >> not compile.


    > > If the object is const, only const functions can be called
    > > on it. If you remove const everywhere, then no functions
    > > can be called on the object. Whence your error.


    > Again, here you have overlooked the call 'F( C() )'.


    Obviously, I was talking about the case of a const C. But
    you're right, I should have made that clearer.

    > Here's a FLAWED analysis, with some facts. Would appreciate
    > it if you could return my help in pointing out flaw in your
    > above explanation, by pointing out flaw(s) in this... :) :)


    Well, I can try, a little, but quite frankly, overload
    resolution is too complicated for me. I just keep it simple,
    and trust the compiler.

    In well designed code, it shouldn't matter which function is
    called. If it matters, they shouldn't be overloaded. But you
    can't always avoid the problem with constructors (since you
    can't give them different names), and the problem can definitly
    occur when software evolves, but must also retain some backwards
    compatibility. And of course, there is still the problem of a
    call being ambiguous.

    > The facts seem to stand.


    > The call


    > F( C() )


    > can be resolved as


    > F( C().operator A() ) // calls F( A const& )


    > or


    > F( C().operator B() ) // calls F( B const& )


    > Data point matrix (apparently these are facts):


    > case const on op A const on op B result
    > 0 no no Ambigious, F(A) or F(B)
    > 1 no YES Ambigious, F(A) or F(B)
    > 2 YES no F(B)
    > 3 YES YES Ambigious, F(A) or F(B)


    That's what g++ (the only compiler I have available here)
    says. The issues are complicated enough that I wouldn't
    count on it being right. (Comeau, or another compiler using
    the EDG front-end, has the best chance of being right, since
    one of the authors of the EDG front-end is also the author
    of section 13 in the standard. But even then, the issues
    are complicated enough that a small slip up cannot be
    excluded.)

    > The most interesting case seems to be case 1. Here, from naïve point
    > of view, the class derivation relationship wants F(B), most specific,
    > but the extra const "conversion" wants F(A), fewest "conversions".


    > However, let's first consider cases 0 and 3, where op A() and op B()
    > compete directly, on equal footing, so to speak.


    > Hm, standard, what do you say?


    > OK, §13.3.3.2/2 is the top-level of how to rank implicit conversion
    > sequences, paraphrased:


    > Best: Standard conversion sequence
    > So-so: User defined conversion sequence
    > Worst: Ellipsis conversion sequence (a "..." formal argument)


    > What we have is two user defined conversion sequences to be
    > compared (from C to A or B result), so that top level ranking
    > doesn't come into play directly, but it can affect rankings
    > for sub-sequences. For a user-defined conversion sequence is
    > defined by §13.3.3.1.2 to consist of a standard conversion
    > sequence followed by a (single) user defined conversion
    > followed by a standard conversion sequence. Sort of like
    > pre-conversion adjustment, real conversion, and post fixups.


    > Case 0
    > Seq Pre Real (user) Post Calls
    > s1 identity op A() A -> A const& F(A const&)
    > s2 identity op B() B -> A const& F(A const&)
    > s3 identity op B() B -> B const& F(B const&)


    > s2 is ranked lower than s3 because the post-conversion of s3
    > (recall, the post conversion is a standard conversion
    > sequence, not involving any calls) is more specific, at least
    > according to my reading of §13.3.3.2/4. So that leaves s1 and
    > s3 to choose from.


    -- Standard conversion sequence S1 is a better
    conversion sequence than standard conversion
    sequence S2 if

    -- S1 is a proper subsequence of S2 (comparing the
    conversion sequences in the canonical form
    defined by 13.3.3.1.1, excluding any Lvalue
    Transformation; the identity conversion sequence
    is considered to be a subsequence of any
    non-identity conversion sequence) or, if not
    that,

    For once, something rather simple and intuitive: since s1 is
    a proper subsequence of s2, s1 is better than s2. (Whatever
    else this means, it means that s2 cannot be chosen.)

    > But s1 and s3 involve the same kinds of conversions.


    > We do not even need to know the exact rules. The
    > specificity of the result of s3 does not enter into the
    > ranking because that specificity is not of a standard
    > conversion sequence: specificity of class affects only
    > ranking of standard conversion (like, you have B, then a B
    > result, doing nothing, is better than direct "upcast" to
    > A, at least according to my reading of §13.3.3.2/4). So
    > in this case s1 and s3, as I understand it, ends up with
    > same rank, and the call is ambigious.


    Sounds right to me. You have a choice of calling F(A
    const&) with an A, or F(B const&) with a B. Intuitively, if
    that isn't ambiguous (supposing that there are no
    differences in the way you obtain the A or the B), I don't
    know what is.

    > *A key notion*: that "closeness" in inheritance only
    > affects ranking of standard conversions, not ranking of a
    > user-defined conversion.


    Yes. A user defined conversion is a user defined
    conversion, and there is no ranking between them, ever. All
    user defined conversions are equal (with regards to the user
    defined conversion---getting the reference to the object may
    involve conversions.

    > Analysis for case 3 would be the same, so, case 1 then:


    > Case 1
    > Seq Pre Real (user) Post Calls
    > s1 identity op A() A -> A const& F(A const&)
    > s2 C -> C const op B() B -> A const& F(A const&)
    > s3 C -> C const op B() B -> B const& F(B const&)


    > Here again s2 is ranked lower than s3. But it would seem
    > that s1 should prevail, should be ranked higher than s3,
    > because of the const conversion in the pre-conversion.
    > However, §13.3.3.2/3 tells us that


    > "User-defined conversion sequence U1 is a better conversion sequence
    > than another user-defined conversion sequence U2 if they contain the
    > same user-defined conversion function or constructor and if the
    > second standard conversion sequence [the "Post" above] of U1 is
    > better than the second standard conversion sequence of U2."


    > And it seems there is no other criterion for top-level
    > ranking of user defined conversion sequences.


    That's the way I read it as well. I'll admit that it's NOT
    what I would intuitively expect: I would expect that if
    there were two conversion sequences involving user defined
    conversions, the pre and the post would be considered. In
    this case, that would mean prefering s1. But that doesn't
    seem to be the case.

    > Hence, in order to for s1 to be better than s3 it would
    > have to involve the same conversion operator, and it would
    > have to be better in the post-conversion. The
    > pre-conversion is simply ignored, wrt. ranking. The
    > result is that s1 and s3 are ranked equally, ambigious.


    > Finally, analysis for case 2:


    > Case 2
    > Seq Pre Real (user) Post Calls
    > s1 C -> C const op A() A -> A const& F(A const&)
    > s2 identity op B() B -> A const& F(A const&)
    > s3 identity op B() B -> B const& F(B const&)


    > But this analysis fails, in the sense that it tells us
    > that since s1 and s3 involve different user defined
    > conversion functions, neither one is ranked better than
    > the other. So according to this analysis they "should" be
    > equally ranked, ambigious. But they're not.


    At least with the compiler(s) we're using. Your reasoning
    seems to hold. (But there *are* 15 pages to be considered,
    so the possibility that we've overlooked something can't be
    excluded.) I'm having a hard time understanding why this is
    different from:

    struct C
    {
    operator std::string const() { return "const" ; }
    operator std::string() { return "non-const" ; } ;
    } ;

    int
    main()
    {
    std::string s1( (C()) ) ;
    std::cout << s1 << std::endl ;
    return 0 ;
    }

    In this case, g++ 4.2.1 says ambiguous as well. So maybe
    you've just found a bug in g++ (or whatever compiler you're
    using).

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, May 18, 2008
    #3
  4. Guest

    On 17 Mag, 00:13, "Alf P. Steinbach" <> wrote:
    > * James Kanze:
    >
    >
    >
    >
    >
    > > On 16 mai, 14:24, wrote:
    > >> I was reading Mr. Alexandrescu's mojo article and I've a hard
    > >> time understanding the following.
    > >> Let's suppose I have:

    >
    > >> //code
    > >> struct A {};

    >
    > >> struct B : A {};

    >
    > >> struct C
    > >> {
    > >>     operator A() const { return A(); }
    > >>     operator B() { return B(); }
    > >> };

    >
    > >> void F( A const & ) {}
    > >> void F( B const & ) {}

    >
    > >> C const H() { return C(); }

    >
    > >> int main()
    > >> {
    > >>     F( C() );               // 1. called with a non-const rvalue
    > >>     F( H() );               // 2. called with a const rvalue}
    > >> }
    > >> //end code

    >
    > >> I understand that if I have a const "C" (rvalue or lvalue,
    > >> here it does not matter) the only option when calling "F"
    > >> would be to use

    >
    > >> C::eek:perator A() const -> F( A const & )

    >
    > > Correct.  The C::eek:perator B() conversion operator cannot be
    > > called (is not a viable function, in the words of the standard).

    >
    > Agreed.
    >
    > >> In the case I have a non-const "C" it seems that the compiler
    > >> chooses

    >
    > >> C::eek:perator B() -> F( B const & )

    >
    > >> my understanding of the article is that this is because since
    > >> B is derived from A, it's a better match than the base class.

    >
    > >> I do not understand then why the constness of operator A()
    > >> makes the difference.

    >
    > > It's rather the non-const-ness of operator B() that makes the
    > > difference.  Because the operator is not const, it cannot be
    > > called on a const object.

    >
    > But here you have overlooked the call 'F( C() )'.
    >
    > Remove the call 'F(H())' and the const on op B still makes a
    > difference... :)
    >
    > OK, I don't understand this, even after scrutinizing the standard, but
    > I recognize that your explanation isn't it, that it ignores the really
    > relevant aspects.  I should understand it, after all it's basic!, and
    > I think I did understand it once, as one of the volunteers helping
    > Andrei with quality assurance on Mojo.  But darned if I now can get my
    > head around this (same predicament as the OP)!
    >
    > >> If I remove it and make it just

    >
    > >> C::eek:perator A()

    >
    > >> my guess would be that that when calling "F" I would always
    > >> get a call to
    > >> F( B const & ). But instead the thing does not compile.

    >
    > > If the object is const, only const functions can be called on
    > > it.  If you remove const everywhere, then no functions can be
    > > called on the object.  Whence your error.

    >
    > Again, here you have overlooked the call 'F( C() )'.
    >
    > Here's a FLAWED analysis, with some facts.  Would appreciate it if you
    > could return my help in pointing out flaw in your above explanation,
    > by pointing out flaw(s) in this... :) :)  The facts seem to stand.
    >
    > The call
    >
    >    F( C() )
    >
    > can be resolved as
    >
    >    F( C().operator A() )         // calls F( A const& )
    >
    > or
    >
    >    F( C().operator B() )         // calls F( B const& )
    >
    > Data point matrix (apparently these are facts):
    >
    >    case   const on op A    const on op B    result
    >      0      no                no              Ambigious, F(A) or F(B)
    >      1      no               YES              Ambigious, F(A) or F(B)
    >      2     YES                no              F(B)
    >      3     YES               YES              Ambigious, F(A) or F(B)
    >
    > The most interesting case seems to be case 1.  Here, from naïve point
    > of view, the class derivation relationship wants F(B), most specific,
    > but the extra const "conversion" wants F(A), fewest "conversions".
    > However, let's first consider cases 0 and 3, where op A() and op B()
    > compete directly, on equal footing, so to speak.
    >
    > Hm, standard, what do you say?
    >
    > OK, §13.3.3.2/2 is the top-level of how to rank implicit conversion
    > sequences, paraphrased:
    >
    >     Best:    Standard conversion sequence
    >     So-so:   User defined conversion sequence
    >     Worst:   Ellipsis conversion sequence (a "..." formal argument)
    >
    > What we have is two user defined conversion sequences to be compared
    > (from C to A or B result), so that top level ranking doesn't come into
    > play directly, but it can affect rankings for sub-sequences.  For a
    > user-defined conversion sequence is defined by §13.3.3.1.2 to consist
    > of a standard conversion sequence followed by a (single) user defined
    > conversion followed by a standard conversion sequence.  Sort of like
    > pre-conversion adjustment, real conversion, and post fixups.
    >
    >    Case 0
    >    Seq    Pre           Real (user)    Post               Calls
    >     s1    identity       op A()        A -> A const&      F(A const&)
    >     s2    identity       op B()        B -> A const&      F(A const&)
    >     s3    identity       op B()        B -> B const&      F(B const&)
    >
    > s2 is ranked lower than s3 because the post-conversion of s3 (recall,
    > the post conversion is a standard conversion sequence, not involving
    > any calls) is more specific, at least according to my reading of
    > §13.3.3.2/4.  So that leaves s1 and s3 to choose from.
    >
    > But s1 and s3 involve the same kinds of conversions.
    >
    > We do not even need to know the exact rules.  The specificity of the
    > result of s3 does not enter into the ranking because that specificity
    > is not of a standard conversion sequence: specificity of class affects
    > only ranking of standard conversion (like, you have B, then a B
    > result, doing nothing, is better than direct "upcast" to A, at least
    > according to my reading of §13.3.3.2/4).  So in this case s1 and s3,
    > as I understand it, ends up with same rank, and the call is ambigious.
    >
    > *A key notion*: that "closeness" in inheritance only affects ranking
    > of standard conversions, not ranking of a user-defined conversion.
    >
    > Analysis for case 3 would be the same, so, case 1 then:
    >
    >    Case 1
    >    Seq    Pre           Real (user)    Post               Calls
    >     s1    identity       op A()        A -> A const&      F(A const&)
    >     s2    C -> C const   op B()        B -> A const&      F(A const&)
    >     s3    C -> C const   op B()        B -> B const&      F(B const&)
    >
    > Here again s2 is ranked lower than s3.  But it would seem that s1
    > should prevail, should be ranked higher than s3, because of the const
    > conversion in the pre-conversion.  However, §13.3.3.2/3 tells us that
    >
    >    "User-defined conversion sequence U1 is a better conversion sequence
    >    than another user-defined conversion sequence U2 if they contain the
    >    same user-defined conversion function or constructor and if the
    >    second standard conversion sequence [the "Post" above] of U1 is
    >    better than the second standard conversion sequence of U2."
    >
    > And it seems there is no other criterion for top-level ranking of user
    > defined conversion sequences.
    >
    > Hence, in order to for s1 to be better than s3 it would have to
    > involve the same conversion operator, and it would have to be better
    > in the post-conversion.  The pre-conversion is simply ignored, wrt.
    > ranking.  The result is that s1 and s3 are ranked equally, ambigious.
    >
    > Finally, analysis for case 2:
    >
    >    Case 2
    >    Seq    Pre           Real (user)    Post               Calls
    >     s1    C -> C const   op A()        A -> A const&      F(A const&)
    >     s2    identity       op B()        B -> A const&      F(A const&)
    >     s3    identity       op B()        B -> B const&      F(B const&)
    >
    > But this analysis fails, in the sense that it tells us that since s1
    > and s3 involve different user defined conversion functions, neither
    > one is ranked better than the other.  So according to this analysis
    > they "should" be equally ranked, ambigious.  But they're not.
    >
    > Cheers,
    >
    > - Alf (perplexed, perhaps needs to read Andrei's article again!)
    >
    > --
    > A: Because it messes up the order in which people normally read text.
    > Q: Why is it such a bad thing?
    > A: Top-posting.
    > Q: What is the most annoying thing on usenet and in e-mail?- Nascondi testo tra virgolette -
    >
    > - Mostra testo tra virgolette -


    Thanks for the detailed analysis Mr. Steinbach.
    I tried to view this issue from a different perspective and I wrote
    the same code using converting constructors instead of conversion ops.
    I feel that what I wrote "means" the same exact thing... but it does
    not compile....

    /*
    // original with conversion ops
    struct B {};

    struct C : B {};

    struct A
    {
    operator B() const { return B(); }
    operator C() { return C(); }
    };
    */

    // different code with conversion constructors
    struct A {};

    struct B
    {
    B() {}
    B( A const & ) {}
    };

    struct C : B
    {
    C() {}
    C( A & ) {}
    };
    //

    void F( B const & ) {}
    void F( C const & ) {}

    int main()
    {
    A obj( ( A() ) );
    F( obj );
    }


    So I'm left with some doubts... Anyway here's the part of
    Mr.Alexandrescu's article that still leaves me puzzled:

    "Why the equal motivation? This is because the non-const to const
    conversion is "frictionless" as far as selecting member functions is
    concerned.

    The need, therefore, is to give the compiler more "motivation" to
    choose the first route than the second. That's where the inheritance
    kicks in. Now the compiler says: "Ok, I guess I could go through
    ConstantString or TemporaryString... but wait, the derived class
    TemporaryString is a better match!"

    The rule in action here is that matching a derived class is considered
    better than matching a base class when selecting a function from an
    overloaded set."

    from
    http://www.ddj.com/cpp/184403855

    Thanks again,
    Francesco

    P.S.
    Would you feel that posting also to clc++mod would get some other
    interesting insights?
     
    , May 19, 2008
    #4
    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. Eph0nk

    Error: Overload resolution failed

    Eph0nk, Oct 23, 2003, in forum: ASP .Net
    Replies:
    0
    Views:
    1,890
    Eph0nk
    Oct 23, 2003
  2. Piotre Ugrumov
    Replies:
    3
    Views:
    397
    Nick Hounsome
    Jan 25, 2004
  3. Peteris Krumins

    Conversions and overload resolution

    Peteris Krumins, Sep 2, 2005, in forum: C++
    Replies:
    1
    Views:
    328
    Philippe Amarenco
    Sep 2, 2005
  4. Anthony Williams
    Replies:
    6
    Views:
    598
    James Kanze
    May 9, 2008
  5. Ying-Chieh Liao

    function overload (not operator overload)

    Ying-Chieh Liao, Oct 11, 2004, in forum: Perl Misc
    Replies:
    3
    Views:
    283
    Sherm Pendley
    Oct 11, 2004
Loading...

Share This Page