function template overloading and typedef in GCC

Discussion in 'C++' started by Arkadiy Vertleyb, Sep 26, 2003.

  1. Hi all,

    I am having a problem trying to overload a function template, based on
    a typedef, such as:

    template<class T>
    struct A
    {};

    template<class T>
    struct B
    {
    typedef A<T> type;
    };

    template<class T>
    void foo(const typename B<T>::type&)
    {}

    void bar()
    {
    foo(B<int>::type());
    }

    g++ 3.3.1 complains at the above code with the following message:
    no matching function for call to `foo(A<int>)'

    Similar code works with no problem in VC6.

    Am I missing something?

    Thanks in advance,

    Arkadiy
    Arkadiy Vertleyb, Sep 26, 2003
    #1
    1. Advertising

  2. Arkadiy Vertleyb wrote:
    > Hi all,
    >
    > I am having a problem trying to overload a function template, based on
    > a typedef, such as:
    >
    > template<class T>
    > struct A
    > {};
    >
    > template<class T>
    > struct B
    > {
    > typedef A<T> type;
    > };
    >
    > template<class T>
    > void foo(const typename B<T>::type&)
    > {}
    >
    > void bar()
    > {
    > foo(B<int>::type());
    > }
    >
    > g++ 3.3.1 complains at the above code with the following message:
    > no matching function for call to `foo(A<int>)'
    >
    > Similar code works with no problem in VC6.
    >
    > Am I missing something?
    >


    Even if this is not allowed by the standard (which I think it is given
    some things I've seen - just a hunch) the error message is totally wrong.

    Besides:

    foo<int>(B<int>::type());

    compiles fine.

    I suggest you post a bug on gcc. Before you do, you might want to try a
    gcc 3.4 devel snapshot. Some template things (like this) have been
    fixed in the development branch.
    Gianni Mariani, Sep 26, 2003
    #2
    1. Advertising

  3. Arkadiy Vertleyb

    tom_usenet Guest

    On 25 Sep 2003 19:27:16 -0700, (Arkadiy Vertleyb)
    wrote:

    >Hi all,
    >
    >I am having a problem trying to overload a function template, based on
    >a typedef, such as:
    >
    >template<class T>
    >struct A
    >{};
    >
    >template<class T>
    >struct B
    >{
    > typedef A<T> type;
    >};
    >
    >template<class T>
    >void foo(const typename B<T>::type&)


    The above contains a non-deducable context (in this case, a nested
    type). This means that calls to the function cannot rely on template
    argument deduction, but must use explicit template argument
    specification.

    The reason this is non-deducable is that the mapping from nested type
    to containing type is not in general one-to-one. Often many different
    Ts would give the same B<T>::type (think specialization of B).

    >{}
    >
    >void bar()
    >{
    > foo(B<int>::type());


    foo<int>(B<int>::type());

    >}


    >g++ 3.3.1 complains at the above code with the following message:
    >no matching function for call to `foo(A<int>)'


    Right.

    >Similar code works with no problem in VC6.


    Yes, this is a bizarre "feature" of VC6 that it deduces this kind of
    non-deducable context.

    >Am I missing something?


    Just that VC6 is very old and non-standard.

    Tom
    tom_usenet, Sep 26, 2003
    #3
  4. tom_usenet wrote:
    > On 25 Sep 2003 19:27:16 -0700, (Arkadiy Vertleyb)
    > wrote:
    >
    >
    >>Hi all,
    >>
    >>I am having a problem trying to overload a function template, based on
    >>a typedef, such as:
    >>
    >>template<class T>
    >>struct A
    >>{};
    >>
    >>template<class T>
    >>struct B
    >>{
    >> typedef A<T> type;
    >>};
    >>
    >>template<class T>
    >>void foo(const typename B<T>::type&)

    >
    >
    > The above contains a non-deducable context (in this case, a nested
    > type).



    What's non-deductible about it ?

    const typename B<T>::type& <<>> B<int>::type

    infers T is int. right ?

    How does the standard define non-deductible ?

    I must admit, I've never come across this kind of problem, so I really
    don't know. Time to brush up ...
    Gianni Mariani, Sep 26, 2003
    #4
  5. Arkadiy Vertleyb

    tom_usenet Guest

    On 26 Sep 2003 14:09:31 GMT, Gianni Mariani <>
    wrote:

    >tom_usenet wrote:
    >> On 25 Sep 2003 19:27:16 -0700, (Arkadiy Vertleyb)
    >> wrote:
    >>
    >>
    >>>Hi all,
    >>>
    >>>I am having a problem trying to overload a function template, based on
    >>>a typedef, such as:
    >>>
    >>>template<class T>
    >>>struct A
    >>>{};
    >>>
    >>>template<class T>
    >>>struct B
    >>>{
    >>> typedef A<T> type;
    >>>};
    >>>
    >>>template<class T>
    >>>void foo(const typename B<T>::type&)

    >>
    >>
    >> The above contains a non-deducable context (in this case, a nested
    >> type).

    >
    >
    >What's non-deductible about it ?


    It attempts to deduce a template parameter from the type of a typedef
    of the template. 14.8.2.4/4 is the relevent bit of the standard.

    >const typename B<T>::type& <<>> B<int>::type
    >
    >infers T is int. right ?


    No, and the deduction can't even reliably be made. e.g.

    template<>
    struct B<float>
    {
    typedef A<int> type; //whoops, now which B?
    };

    Of course, this could just cause an ambiguity error, as it does in
    VC6. However, the mapping from inner type to template parameter is not
    always many-to-one, so the committee decided to forbid it.

    >
    >How does the standard define non-deductible ?


    Read up on nondeduced contexts.

    Tom
    tom_usenet, Sep 26, 2003
    #5
  6. Hi guys,

    Thanks for your responce.

    Come to think about it, I do realize that overloading on a nested
    typedef in this context (at least in my case) doesn't make a lot of
    sense. The nested typedef may after all resolve to different types,
    like:

    template<class T>
    struct A1
    {};

    template<class T>
    struct A2
    {};

    template<class T>
    struct B
    {
    // something like:
    typedef select<some_condition_based_on_T, A1<T>, A2<T> >::type type;
    };

    For both A1 and A2 I need to define a separate overloaded function.
    So I actually have to overload on A1<T> and A2<T>, rather than on
    B<T>::type.

    Regards,

    Arkadiy


    tom_usenet <> wrote in message news:<>...
    > On 26 Sep 2003 14:09:31 GMT, Gianni Mariani <>
    > wrote:
    >
    > >tom_usenet wrote:
    > >> On 25 Sep 2003 19:27:16 -0700, (Arkadiy Vertleyb)
    > >> wrote:
    > >>
    > >>
    > >>>Hi all,
    > >>>
    > >>>I am having a problem trying to overload a function template, based on
    > >>>a typedef, such as:
    > >>>
    > >>>template<class T>
    > >>>struct A
    > >>>{};
    > >>>
    > >>>template<class T>
    > >>>struct B
    > >>>{
    > >>> typedef A<T> type;
    > >>>};
    > >>>
    > >>>template<class T>
    > >>>void foo(const typename B<T>::type&)
    > >>
    > >>
    > >> The above contains a non-deducable context (in this case, a nested
    > >> type).

    > >
    > >
    > >What's non-deductible about it ?

    >
    > It attempts to deduce a template parameter from the type of a typedef
    > of the template. 14.8.2.4/4 is the relevent bit of the standard.
    >
    > >const typename B<T>::type& <<>> B<int>::type
    > >
    > >infers T is int. right ?

    >
    > No, and the deduction can't even reliably be made. e.g.
    >
    > template<>
    > struct B<float>
    > {
    > typedef A<int> type; //whoops, now which B?
    > };
    >
    > Of course, this could just cause an ambiguity error, as it does in
    > VC6. However, the mapping from inner type to template parameter is not
    > always many-to-one, so the committee decided to forbid it.
    >
    > >
    > >How does the standard define non-deductible ?

    >
    > Read up on nondeduced contexts.
    >
    > Tom
    Arkadiy Vertleyb, Sep 27, 2003
    #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. Iyer, Prasad C

    Overloading __init__ & Function overloading

    Iyer, Prasad C, Sep 30, 2005, in forum: Python
    Replies:
    3
    Views:
    6,404
    Fredrik Lundh
    Sep 30, 2005
  2. Replies:
    5
    Views:
    357
    Nathan Addy
    Sep 17, 2005
  3. flopbucket
    Replies:
    6
    Views:
    455
    Victor Bazarov
    Aug 17, 2006
  4. oor
    Replies:
    0
    Views:
    1,343
  5. Replies:
    2
    Views:
    800
Loading...

Share This Page