Overload lookup of pointer-to-member

Discussion in 'C++' started by jknupp@gmail.com, Jul 12, 2008.

  1. Guest

    In the following program, if the call to bar does not specify the type
    as <int>, gcc gives the error "no matching function for call to
    ‘bar(A&, <unresolved overloaded function type>)’". Since bar
    explicitly takes a pointer-to-member with no parameters, why is the
    lookup for the overloaded function not able to use the number of
    arguments to determine the appropriate function? Is there a relevant
    portion of the standard that governs the lookup rules in this case?

    Thanks in advance,
    Jeff

    #include <iostream>
    using namespace std;

    class A
    {
    public:
    int foo()
    {
    cout << "int foo" << endl;
    return 5;
    }
    template <class A>
    void foo (A a)
    {
    cout << "template foo" << endl;
    }
    };

    template <class Type, class Obj>
    void bar (Obj& obj, Type (Obj::*func)())
    {
    Type t = (obj.*func)();
    cout << "TYPE: " << t << endl;
    }
    int main ()
    {
    A a;
    bar<int>(a, &A::foo); //<int> required, even though only one of the
    functions takes no arguments
    bar(a, &A::foo); //doesn't compile
    }
    , Jul 12, 2008
    #1
    1. Advertising

  2. On Jul 12, 8:14 am, "" <> wrote:
    > In the following program, if the call to bar does not specify the type
    > as <int>, gcc gives the error "no matching function for call to
    > ‘bar(A&, <unresolved overloaded function type>)’". Since bar
    > explicitly takes a pointer-to-member with no parameters, why is the
    > lookup for the overloaded function not able to use the number of
    > arguments to determine the appropriate function? Is there a relevant
    > portion of the standard that governs the lookup rules in this case?
    >
    > Thanks in advance,
    > Jeff
    >
    > #include <iostream>
    > using namespace std;
    >
    > class A
    > {
    > public:
    > int foo()
    > {
    > cout << "int foo" << endl;
    > return 5;
    > }
    > template <class A>
    > void foo (A a)
    > {
    > cout << "template foo" << endl;
    > }
    >
    > };
    >
    > template <class Type, class Obj>
    > void bar (Obj& obj, Type (Obj::*func)())
    > {
    > Type t = (obj.*func)();
    > cout << "TYPE: " << t << endl;}
    >
    > int main ()
    > {
    > A a;
    > bar<int>(a, &A::foo); //<int> required, even though only one of the
    > functions takes no arguments
    > bar(a, &A::foo); //doesn't compile
    > }


    Compiles fine with Comeau online and VC++ 2005. So, could be there's
    something wrong with g++ (an older version, may be).
    Abhishek Padmanabh, Jul 12, 2008
    #2
    1. Advertising

  3. Guest

    On Jul 12, 3:49 am, Abhishek Padmanabh <>
    wrote:
    > On Jul 12, 8:14 am, "" <> wrote:
    >
    >
    >
    > > In the following program, if the call to bar does not specify the type
    > > as <int>, gcc gives the error "no matching function for call to
    > > ‘bar(A&, <unresolved overloaded function type>)’". Since bar
    > > explicitly takes a pointer-to-member with no parameters, why is the
    > > lookup for the overloaded function not able to use the number of
    > > arguments to determine the appropriate function? Is there a relevant
    > > portion of the standard that governs the lookup rules in this case?

    >
    > > Thanks in advance,
    > > Jeff

    >
    > > #include <iostream>
    > > using namespace std;

    >
    > > class A
    > > {
    > >         public:
    > >         int foo()
    > >         {
    > >                 cout << "int foo" << endl;
    > >                 return 5;
    > >         }
    > >         template <class A>
    > >         void foo (A a)
    > >         {
    > >                 cout << "template foo" << endl;
    > >         }

    >
    > > };

    >
    > > template <class Type, class Obj>
    > > void bar (Obj& obj, Type (Obj::*func)())
    > > {
    > >         Type t = (obj.*func)();
    > >         cout << "TYPE: " << t << endl;}

    >
    > > int main ()
    > > {
    > >         A a;
    > >         bar<int>(a, &A::foo); //<int> required, even though only one of the
    > > functions takes no arguments
    > >         bar(a, &A::foo); //doesn't compile
    > > }

    >
    > Compiles fine with Comeau online and VC++ 2005. So, could be there's
    > something wrong with g++ (an older version, may be).


    I had tried using gcc 4.2.3 (where it failed) and VC++6 (where it
    worked). I'm really interested in if it's supposed to work (i.e. both
    comeau and VC++ are complying with the standard in this case) or an
    actual bug in gcc.

    Thanks,
    Jeff
    , Jul 12, 2008
    #3
  4. Guest

    On 12 juil, 15:06, "" <> wrote:
    > On Jul 12, 3:49 am, Abhishek Padmanabh <>
    > wrote:
    >
    >
    > > On Jul 12, 8:14 am, "" <> wrote:

    >
    > > > In the following program, if the call to bar does not specify the type
    > > > as <int>, gcc gives the error "no matching function for call to
    > > > ‘bar(A&, <unresolved overloaded function type>)’". Since bar
    > > > explicitly takes a pointer-to-member with no parameters, why is the
    > > > lookup for the overloaded function not able to use the number of
    > > > arguments to determine the appropriate function? Is there a relevant
    > > > portion of the standard that governs the lookup rules in this case?

    >
    > > > Thanks in advance,
    > > > Jeff

    >
    > > > #include <iostream>
    > > > using namespace std;

    >
    > > > class A
    > > > {
    > > >         public:
    > > >         int foo()
    > > >         {
    > > >                 cout << "int foo" << endl;
    > > >                 return 5;
    > > >         }
    > > >         template <class A>
    > > >         void foo (A a)
    > > >         {
    > > >                 cout << "template foo" << endl;
    > > >         }

    >
    > > > };

    >
    > > > template <class Type, class Obj>
    > > > void bar (Obj& obj, Type (Obj::*func)())
    > > > {
    > > >         Type t = (obj.*func)();
    > > >         cout << "TYPE: " << t << endl;}

    >
    > > > int main ()
    > > > {
    > > >         A a;
    > > >         bar<int>(a, &A::foo); //<int> required, even though only one of the
    > > > functions takes no arguments
    > > >         bar(a, &A::foo); //doesn't compile
    > > > }

    >
    > > Compiles fine with Comeau online and VC++ 2005. So, could be there's
    > > something wrong with g++ (an older version, may be).

    >
    > I had tried using gcc 4.2.3 (where it failed) and VC++6 (where it
    > worked). I'm really interested in if it's supposed to work (i.e. both
    > comeau and VC++ are complying with the standard in this case) or an
    > actual bug in gcc.
    >
    > Thanks,
    > Jeff


    GCC is right because the overload resolution set of &A::foo contains a
    function template.

    Alexandre Courpron.
    , Jul 12, 2008
    #4
  5. James Kanze Guest

    On Jul 12, 9:49 am, Abhishek Padmanabh <>
    wrote:
    > On Jul 12, 8:14 am, "" <> wrote:
    > > In the following program, if the call to bar does not
    > > specify the type as <int>, gcc gives the error "no matching
    > > function for call to ‘bar(A&, <unresolved overloaded
    > > function type>)’". Since bar explicitly takes a
    > > pointer-to-member with no parameters, why is the lookup for
    > > the overloaded function not able to use the number of
    > > arguments to determine the appropriate function? Is there a
    > > relevant portion of the standard that governs the lookup
    > > rules in this case?


    > > #include <iostream>
    > > using namespace std;


    > > class A
    > > {
    > > public:
    > > int foo()
    > > {
    > > cout << "int foo" << endl;
    > > return 5;
    > > }
    > > template <class A>
    > > void foo (A a)
    > > {
    > > cout << "template foo" << endl;
    > > }
    > > };


    > > template <class Type, class Obj>
    > > void bar (Obj& obj, Type (Obj::*func)())
    > > {
    > > Type t = (obj.*func)();
    > > cout << "TYPE: " << t << endl;
    > > }


    > > int main ()
    > > {
    > > A a;
    > > bar<int>(a, &A::foo); //<int> required, even though only one of the
    > > functions takes no arguments
    > > bar(a, &A::foo); //doesn't compile
    > > }


    > Compiles fine with Comeau online and VC++ 2005. So, could be
    > there's something wrong with g++ (an older version, may be).


    I don't know. The problem isn't overload resolution per se, but
    template type deduction, which has a completely different set of
    rules. In this case, I'll admit that I don't understand the
    rules enough to be sure, but off hand, I don't think it is
    supposed to work. The compiler can't effectively do the type
    deduction for bar until it has resolved the overloading of
    &A::foo, and it can't resolve this overloading until it knows
    the type &A::foo is being used to initialize.

    --
    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, Jul 12, 2008
    #5
  6. Guest

    On Jul 12, 3:24 pm, James Kanze <> wrote:
    > On Jul 12, 9:49 am, Abhishek Padmanabh <>
    > wrote:
    >
    >
    >
    > > On Jul 12, 8:14 am, "" <> wrote:
    > > > In the following program, if the call to bar does not
    > > > specify the type as <int>, gcc gives the error "no matching
    > > > function for call to ‘bar(A&, <unresolved overloaded
    > > > function type>)’". Since bar explicitly takes a
    > > > pointer-to-member with no parameters, why is the lookup for
    > > > the overloaded function not able to use the number of
    > > > arguments to determine the appropriate function? Is there a
    > > > relevant portion of the standard that governs the lookup
    > > > rules in this case?
    > > > #include <iostream>
    > > > using namespace std;
    > > > class A
    > > > {
    > > >         public:
    > > >         int foo()
    > > >         {
    > > >                 cout << "int foo" << endl;
    > > >                 return 5;
    > > >         }
    > > >         template <class A>
    > > >         void foo (A a)
    > > >         {
    > > >                 cout << "template foo" << endl;
    > > >         }
    > > > };
    > > > template <class Type, class Obj>
    > > > void bar (Obj& obj, Type (Obj::*func)())
    > > > {
    > > >         Type t = (obj.*func)();
    > > >         cout << "TYPE: " << t << endl;
    > > > }
    > > > int main ()
    > > > {
    > > >         A a;
    > > >         bar<int>(a, &A::foo); //<int> required, even though only one of the
    > > > functions takes no arguments
    > > >         bar(a, &A::foo); //doesn't compile
    > > > }

    > > Compiles fine with Comeau online and VC++ 2005. So, could be
    > > there's something wrong with g++ (an older version, may be).

    >
    > I don't know.  The problem isn't overload resolution per se, but
    > template type deduction, which has a completely different set of
    > rules.  In this case, I'll admit that I don't understand the
    > rules enough to be sure, but off hand, I don't think it is
    > supposed to work.  The compiler can't effectively do the type
    > deduction for bar until it has resolved the overloading of
    > &A::foo, and it can't resolve this overloading until it knows
    > the type &A::foo is being used to initialize.
    >

    In this case, though, it shouldn't necessarily need to know the return
    type to determine the proper overloaded function as it can use the
    number of arguments. I'm just a bit confused about the order in which
    the two actions are applied (the type deduction and the overload
    resolution) and the rules/precedence for resolving overloads when
    function templates are involved.
    > --
    > 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


    Thanks,
    Jeff
    , Jul 13, 2008
    #6
  7. James Kanze Guest

    On Jul 13, 5:44 am, "" <> wrote:
    > On Jul 12, 3:24 pm, James Kanze <> wrote:


    > > On Jul 12, 9:49 am, Abhishek Padmanabh
    > > <> wrote:


    > > > On Jul 12, 8:14 am, "" <> wrote:


    [...]
    > > > > #include <iostream>
    > > > > using namespace std;
    > > > > class A
    > > > > {
    > > > > public:
    > > > > int foo()
    > > > > {
    > > > > cout << "int foo" << endl;
    > > > > return 5;
    > > > > }
    > > > > template <class A>
    > > > > void foo (A a)
    > > > > {
    > > > > cout << "template foo" << endl;
    > > > > }
    > > > > };
    > > > > template <class Type, class Obj>
    > > > > void bar (Obj& obj, Type (Obj::*func)())
    > > > > {
    > > > > Type t = (obj.*func)();
    > > > > cout << "TYPE: " << t << endl;
    > > > > }
    > > > > int main ()
    > > > > {
    > > > > A a;
    > > > > bar<int>(a, &A::foo); //<int> required, even though only one of the
    > > > > functions takes no arguments
    > > > > bar(a, &A::foo); //doesn't compile
    > > > > }
    > > > Compiles fine with Comeau online and VC++ 2005. So, could
    > > > be there's something wrong with g++ (an older version, may
    > > > be).


    > > I don't know. The problem isn't overload resolution per se,
    > > but template type deduction, which has a completely
    > > different set of rules. In this case, I'll admit that I
    > > don't understand the rules enough to be sure, but off hand,
    > > I don't think it is supposed to work. The compiler can't
    > > effectively do the type deduction for bar until it has
    > > resolved the overloading of &A::foo, and it can't resolve
    > > this overloading until it knows the type &A::foo is being
    > > used to initialize.


    > In this case, though, it shouldn't necessarily need to know
    > the return type to determine the proper overloaded function as
    > it can use the number of arguments.


    It can't even start overload resolution until it has done type
    deduction. Until the compiler has deduced the type of bar, it
    can't consider what instances of foo are value. And until knows
    the type of &A::foo, it can't deduce the type of bar.

    > I'm just a bit confused about the order in which the two
    > actions are applied (the type deduction and the overload
    > resolution) and the rules/precedence for resolving overloads
    > when function templates are involved.


    The complete rules are far from simple, but the basic principle
    is that the compiler first constructs a set of all possible
    overloaded, then does type deduction on the templates, replacing
    each template in the initial set with an actual instantiation
    (or dropping it completely---substitution failure is not an
    error), and only then procedes to overload resolution (the first
    step of which is to throw out any functions which cannot be
    called. In this particular case, there are two overload
    resolutions involved: one for bar and one for foo, but that
    doesn't change the basic principles. In order to procede with
    the process for &A::foo, it must know the exact target type.
    And in order to know the target type, it must have successfully
    resolved the overload of bar, which means that it has to have
    successfully done type deduction for the template bar. Which
    requires knowing which overload of &A::foo was chosen.

    As an intelligent human, you can easily solve the problem, but
    if you think about it, in solving it, you jump back and forth,
    first elimiating some of the overloads for foo (without having
    all of the necessary information for full overload resolution),
    using intuitive information about the possible results. The
    compiler can only do one thing after the other, and in this
    case, you have a circular dependency for it: to do A, it must
    first do B, and to do B, it must first do A. It doesn't have
    enough imagination to be able to speculatively do A and B in
    parallel.

    --
    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, Jul 13, 2008
    #7
  8. Guest

    On 13 juil, 05:44, "" <> wrote:
    > On Jul 12, 3:24 pm, James Kanze <> wrote:
    >
    > > I don't know.  The problem isn't overload resolution per se, but
    > > template type deduction, which has a completely different set of
    > > rules.  In this case, I'll admit that I don't understand the
    > > rules enough to be sure, but off hand, I don't think it is
    > > supposed to work.  The compiler can't effectively do the type
    > > deduction for bar until it has resolved the overloading of
    > > &A::foo, and it can't resolve this overloading until it knows
    > > the type &A::foo is being used to initialize.

    >
    > In this case, though, it shouldn't necessarily need to know the return
    > type to determine the proper overloaded function as it can use the
    > number of arguments. I'm just a bit confused about the order in which
    > the two actions are applied (the type deduction and the overload
    > resolution)


    Overload resolution comes before type deduction.

    > and the rules/precedence for resolving overloads when
    > function templates are involved.


    As I said earlier, when function templates are involved, type
    deduction fails. Your code is non-standard. It would be standard if
    you replaced the function template foo by a non-template version.

    Alexandre Courpron.
    , Jul 13, 2008
    #8
  9. Guest

    On Jul 13, 4:53 am, wrote:
    > On 13 juil, 05:44, "" <> wrote:
    >
    >
    >
    >
    >
    > > On Jul 12, 3:24 pm, James Kanze <> wrote:

    >
    > > > I don't know.  The problem isn't overload resolution per se, but
    > > > template type deduction, which has a completely different set of
    > > > rules.  In this case, I'll admit that I don't understand the
    > > > rules enough to be sure, but off hand, I don't think it is
    > > > supposed to work.  The compiler can't effectively do the type
    > > > deduction for bar until it has resolved the overloading of
    > > > &A::foo, and it can't resolve this overloading until it knows
    > > > the type &A::foo is being used to initialize.

    >
    > > In this case, though, it shouldn't necessarily need to know the return
    > > type to determine the proper overloaded function as it can use the
    > > number of arguments. I'm just a bit confused about the order in which
    > > the two actions are applied (the type deduction and the overload
    > > resolution)

    >
    > Overload resolution comes before type deduction.
    >

    Understood. Do you know where this is mentioned in the standard?

    > > and the rules/precedence for resolving overloads when
    > > function templates are involved.

    >
    > As I said earlier, when function templates are involved, type
    > deduction fails. Your code is non-standard. It would be standard if
    > you replaced the function template foo by a non-template version.
    >


    Assuming you are saying that this particular combination of type
    deduciton and overload resolution will not work, and not that the
    standard prevents you from overloading a funciton template with a non-
    template function (which is not true), is there a way to acheive the
    same effect in a compliant way? In the acutal code, the bar function
    takes additional parameters (a field name) and is used to copy a
    subset of the values of A (the foo functions represent accessors and
    mutators of A) on a seperate object. What I would rather not do is be
    forced to specify the bar<int>, which would be different for each
    accessor of A and subject to change.

    > Alexandre Courpron.- Hide quoted text -
    >
    > - Show quoted text -


    Thanks,
    Jeff
    , Jul 13, 2008
    #9
  10. Guest

    On Jul 13, 4:47 am, James Kanze <> wrote:
    > On Jul 13, 5:44 am, "" <> wrote:
    >
    > > On Jul 12, 3:24 pm, James Kanze <> wrote:
    > > > On Jul 12, 9:49 am, Abhishek Padmanabh
    > > > <> wrote:
    > > > > On Jul 12, 8:14 am, "" <> wrote:

    >
    >     [...]
    >
    >
    >
    >
    >
    > > > > > #include <iostream>
    > > > > > using namespace std;
    > > > > > class A
    > > > > > {
    > > > > >         public:
    > > > > >         int foo()
    > > > > >         {
    > > > > >                 cout << "int foo" << endl;
    > > > > >                 return 5;
    > > > > >         }
    > > > > >         template <class A>
    > > > > >         void foo (A a)
    > > > > >         {
    > > > > >                 cout << "template foo" << endl;
    > > > > >         }
    > > > > > };
    > > > > > template <class Type, class Obj>
    > > > > > void bar (Obj& obj, Type (Obj::*func)())
    > > > > > {
    > > > > >         Type t = (obj.*func)();
    > > > > >         cout << "TYPE: " << t << endl;
    > > > > > }
    > > > > > int main ()
    > > > > > {
    > > > > >         A a;
    > > > > >         bar<int>(a, &A::foo); //<int> required, even though only one of the
    > > > > > functions takes no arguments
    > > > > >         bar(a, &A::foo); //doesn't compile
    > > > > > }
    > > > > Compiles fine with Comeau online and VC++ 2005. So, could
    > > > > be there's something wrong with g++ (an older version, may
    > > > > be).
    > > > I don't know.  The problem isn't overload resolution per se,
    > > > but template type deduction, which has a completely
    > > > different set of rules.  In this case, I'll admit that I
    > > > don't understand the rules enough to be sure, but off hand,
    > > > I don't think it is supposed to work.  The compiler can't
    > > > effectively do the type deduction for bar until it has
    > > > resolved the overloading of &A::foo, and it can't resolve
    > > > this overloading until it knows the type &A::foo is being
    > > > used to initialize.

    > > In this case, though, it shouldn't necessarily need to know
    > > the return type to determine the proper overloaded function as
    > > it can use the number of arguments.

    >
    > It can't even start overload resolution until it has done type
    > deduction.  Until the compiler has deduced the type of bar, it
    > can't consider what instances of foo are value.  And until knows
    > the type of &A::foo, it can't deduce the type of bar.
    >
    > > I'm just a bit confused about the order in which the two
    > > actions are applied (the type deduction and the overload
    > > resolution) and the rules/precedence for resolving overloads
    > > when function templates are involved.

    >
    > The complete rules are far from simple, but the basic principle
    > is that the compiler first constructs a set of all possible
    > overloaded, then does type deduction on the templates, replacing
    > each template in the initial set with an actual instantiation
    > (or dropping it completely---substitution failure is not an
    > error), and only then procedes to overload resolution (the first
    > step of which is to throw out any functions which cannot be
    > called.  In this particular case, there are two overload
    > resolutions involved: one for bar and one for foo, but that
    > doesn't change the basic principles.  In order to procede with
    > the process for &A::foo, it must know the exact target type.
    > And in order to know the target type, it must have successfully
    > resolved the overload of bar, which means that it has to have
    > successfully done type deduction for the template bar.  Which
    > requires knowing which overload of &A::foo was chosen.
    >


    Thanks, this is what I had assumed. What is still a bit unclear to me,
    though, is that Type is being used as the return type of foo, which I
    didn't think participated in overload resolution. At the point that it
    is resolving the overload for foo (and thus deducing the types for
    bar), wouldn't Type be extraneous information? If not, it seems that
    if you were to replace the templated foo with 'int foo(int arg)' that
    the amount of information is the same with respect to overload
    resolution, yet the latter case will work.

    > As an intelligent human, you can easily solve the problem, but
    > if you think about it, in solving it, you jump back and forth,
    > first elimiating some of the overloads for foo (without having
    > all of the necessary information for full overload resolution),
    > using intuitive information about the possible results.  The
    > compiler can only do one thing after the other, and in this
    > case, you have a circular dependency for it: to do A, it must
    > first do B, and to do B, it must first do A.  It doesn't have
    > enough imagination to be able to speculatively do A and B in
    > parallel.
    >


    Again, I understand you point here, but that presupposes that they
    return type for foo is relevant. I was under the impression that it
    wasn't for overload resolution (at least at the resolution stage we
    are at), but obviously may be mistaken.

    Thanks,
    Jeff
    , Jul 13, 2008
    #10
  11. James Kanze Guest

    On Jul 13, 6:45 pm, "" <> wrote:
    > On Jul 13, 4:47 am, James Kanze <> wrote:


    [...]
    > Thanks, this is what I had assumed. What is still a bit
    > unclear to me, though, is that Type is being used as the
    > return type of foo, which I didn't think participated in
    > overload resolution.


    It doesn't, but...

    In your example, the overload resolution of &T::foo was a
    special case; the overload resolution of &T::foo depends on the
    type it is initializing or being assigned to. And until the
    compiler has done the type deduction of bar, the parameters
    don't have a type, so neither type deduction nor overload
    resolution can proceed. The return type of the pointer to
    function parameter will be ignored once overload resolution for
    &T::foo is invoked, but the compiler can't even get that far.

    > At the point that it is resolving the overload for foo (and
    > thus deducing the types for bar), wouldn't Type be extraneous
    > information?


    If the compiler got that far.

    > If not, it seems that if you were to replace the templated foo
    > with 'int foo(int arg)' that the amount of information is the
    > same with respect to overload resolution, yet the latter case
    > will work.


    No, because the compiler can't start working until it has
    deduced the actual type of foo. Which in turn depends on the
    actual type of the parameter. Which depends on the type of the
    argument. Which is what we're trying to deduce. The fact that
    the return type will not be used in the overload resolution
    later doesn't stop the compiler from having to deduce it. In
    the end, the compiler will have to know the return type of both
    the pointer to member function, and the function whose address
    is being assigned to it. And there are no provisions for the
    compiler to do partial type deduction on the parameter, skipping
    the return type, then do overload resolution (with the
    associated type deduction on the template functions), then come
    back and finish the type deduction on bar.

    > > As an intelligent human, you can easily solve the problem, but
    > > if you think about it, in solving it, you jump back and forth,
    > > first elimiating some of the overloads for foo (without having
    > > all of the necessary information for full overload resolution),
    > > using intuitive information about the possible results. The
    > > compiler can only do one thing after the other, and in this
    > > case, you have a circular dependency for it: to do A, it must
    > > first do B, and to do B, it must first do A. It doesn't have
    > > enough imagination to be able to speculatively do A and B in
    > > parallel.


    > Again, I understand you point here, but that presupposes that
    > they return type for foo is relevant.


    It is, in the end. It is needed to deduce the template
    arguments for bar. And until those template arguments are
    deduced, the "pointer to function" doesn't have a known type,
    and the compiler cannot proceed with overload resolution on the
    argument. The fact that the return type is not used in this
    overload resolution is irrelevant; for the overload resolution
    to start, the type must be known.

    (Actually, I'm not even 100% certain that you can say that the
    return type is irrelevant here. Taking the address of a
    function is a special case, where the use is taken into account.
    But it doesn't matter, because you don't get that far.)

    > I was under the impression that it wasn't for overload
    > resolution (at least at the resolution stage we are at), but
    > obviously may be mistaken.


    Again, you're failing before overload resolution starts.

    --
    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, Jul 13, 2008
    #11
  12. Guest

    On 13 juil, 18:34, "" <> wrote:
    > On Jul 13, 4:53 am, wrote:
    >
    >
    > > On 13 juil, 05:44, "" <> wrote:

    >
    > > > In this case, though, it shouldn't necessarily need to know the return
    > > > type to determine the proper overloaded function as it can use the
    > > > number of arguments. I'm just a bit confused about the order in which
    > > > the two actions are applied (the type deduction and the overload
    > > > resolution)

    >
    > > Overload resolution comes before type deduction.

    >
    > Understood. Do you know where this is mentioned in the standard?



    14.8.2.2/1 : "Template arguments can be deduced from the type
    specified when taking the address of an overloaded function."


    As soon as type deduction handles adresses of overload functions, then
    the whole type deduction process must complete after overload
    resolution (otherwise it could lead to ambiguous cases) . However, I
    would rather see overload resolution as a step in the type deduction
    process and that step is generally the final one.

    But, in our case, it is not the final step. If some types of the
    signature of the overloaded function must be deduced and that
    deduction can't be "directly" done from the function call (explicit
    template specialization,...), then there is what we can call "template
    overload resolution" : type deduction will check if the overload set
    provides a match for the "template signature" (that overload set must
    not contain function template). From that "template overload
    resolution", type deduction can take from the matched candidate the
    correct types.


    > > As I said earlier, when function templates are involved, type
    > > deduction fails. Your code is non-standard. It would be standard if
    > > you replaced the function template foo by a non-template version.

    >
    > Assuming you are saying that this particular combination of type
    > deduciton and overload resolution will not work, and not that the
    > standard prevents you from overloading a funciton template with a non-
    > template function (which is not true), is there a way to acheive the
    > same effect in a compliant way? In the acutal code, the bar function
    > takes additional parameters (a field name) and is used to copy a
    > subset of the values of A (the foo functions represent accessors and
    > mutators of A) on a seperate object. What I would rather not do is be
    > forced to specify the bar<int>, which would be different for each
    > accessor of A and subject to change.
    >


    If it's different for each accessor and subject to change, then
    encapsulate it.
    Slight modification of your example :

    #include <iostream>
    using namespace std;

    class A
    {
    public:
    typedef int return_type; // type trait
    int foo()
    {
    cout << "int foo" << endl;
    return 5;
    }
    template <class A>
    void foo (A a)
    {
    cout << "template foo" << endl;
    }
    };

    template <class Obj>
    void bar (Obj& obj, typename Obj::return_type (Obj::*func)())
    {
    typename Obj::return_type t = (obj.*func)();
    cout << "TYPE: " << t << endl;
    }
    int main ()
    {
    A a;
    bar(a, &A::foo); // should compile on a conforming compiler
    }


    Here, every part of the foo signature can be directly deduced from the
    function call (from &A::foo) without resorting to "template overload
    resolution", then it doesn't matter whether there is a function
    template in the foo overload set.


    Alexandre Courpron.
    , Jul 13, 2008
    #12
    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. Piotre Ugrumov
    Replies:
    3
    Views:
    368
    Nick Hounsome
    Jan 25, 2004
  2. Fraser Ross
    Replies:
    4
    Views:
    1,039
    Fraser Ross
    Aug 14, 2004
  3. Ying-Chieh Liao

    function overload (not operator overload)

    Ying-Chieh Liao, Oct 11, 2004, in forum: Perl Misc
    Replies:
    3
    Views:
    248
    Sherm Pendley
    Oct 11, 2004
  4. Stephen Howe
    Replies:
    2
    Views:
    285
    Stephen Howe
    Nov 6, 2012
  5. W Karas
    Replies:
    3
    Views:
    253
    Victor Bazarov
    Nov 30, 2012
Loading...

Share This Page