point of definition or instantiation of a template

Discussion in 'C++' started by ES Kim, Apr 14, 2005.

  1. ES Kim

    ES Kim Guest

    Please consider this code:

    void foo(int);

    template<typename T>
    struct S
    {
    void f()
    {
    foo(1); // (1)
    T t;
    foo(t); // (2)
    }
    };

    void foo(int*);

    // <--- point of instantiation
    int main()
    {
    S<int*> a;
    a.f();
    }

    In (1), foo is not a dependent name, so point of definition binding applies
    and void foo(int) is called. But what about (2)? I think foo IS a dependent
    name there and point of instantiation binding applies. At that point,
    void foo(int*) is in scope, which means the code has no problem.
    But Comeau rejects the code. Is it correct or not?

    --
    ES Kim
    ES Kim, Apr 14, 2005
    #1
    1. Advertising

  2. ES Kim wrote:
    > Please consider this code:
    >
    > void foo(int);
    >
    > template<typename T>
    > struct S
    > {
    > void f()
    > {
    > foo(1); // (1)
    > T t;
    > foo(t); // (2)
    > }
    > };
    >
    > void foo(int*);
    >
    > // <--- point of instantiation
    > int main()
    > {
    > S<int*> a;
    > a.f();
    > }
    >
    > In (1), foo is not a dependent name, so point of definition binding applies
    > and void foo(int) is called. But what about (2)? I think foo IS a dependent
    > name there


    You made me look up the rules for dependent names, and, yes, you're
    correct here, 'foo' is a dependent name.

    > and point of instantiation binding applies. At that point,
    > void foo(int*) is in scope, which means the code has no problem.
    > But Comeau rejects the code. Is it correct or not?


    Seems to be a bug. Have you tried contacting Comeau?

    FWIW, Visual C++ 2003 gets it right. g++ v2.95.2 gets it right. g++
    v3.2.2 gets it right. MIPSpro v7.4 gets it right. HP's aCC v3.50 gets
    it right... I decided to stop at that point.

    V
    Victor Bazarov, Apr 14, 2005
    #2
    1. Advertising

  3. ES Kim wrote in news:d3kocl$nfm$ in comp.lang.c++:

    > Please consider this code:
    >
    > void foo(int);
    >
    > template<typename T>
    > struct S
    > {
    > void f()
    > {
    > foo(1); // (1)
    > T t;
    > foo(t); // (2)
    > }
    > };
    >
    > void foo(int*);
    >
    > // <--- point of instantiation
    > int main()
    > {
    > S<int*> a;
    > a.f();
    > }
    >
    > In (1), foo is not a dependent name, so point of definition binding
    > applies and void foo(int) is called. But what about (2)?


    (2) is a dependant name, it depends on T a template paramiter, it can be
    nothing else.

    > I think foo
    > IS a dependent name there and point of instantiation binding applies.


    foo( t ) (2) can only be bound to function's that were declared prior
    to the defenition (body) of S<>:f(), only function's found by ADL
    (Argument dependent Lookup) are allowed to bypass this rule.

    In this case its foo( int ) as that is the *only* foo available when
    S<>::f() is parsed.

    > At that point, void foo(int*) is in scope,


    foo(int *) is an overload of foo(int) however it isn't found by ADL
    as ADL isn't used when all paramiters are pure inbult types (int,
    int * etc).

    For ADL to be used T would need to be declared in a different namespace
    to S<>, in which case the compiler would use ADL to look for overloads
    foo( convertible_from_T ) in T's namespace, whether or not they were
    declared before the defenition of s<>::f().

    > which means the code has no
    > problem. But Comeau rejects the code. Is it correct or not?
    >


    Its correct an int * can't be converted to an int without a cast.

    Rob.
    --
    http://www.victim-prime.dsl.pipex.com/
    Rob Williscroft, Apr 14, 2005
    #3
  4. ES Kim

    ES Kim Guest

    "Victor Bazarov" <> wrote in message
    news:eek:mu7e.63200$01.us.to.verio.net...
    > ES Kim wrote:
    > > and point of instantiation binding applies. At that point,
    > > void foo(int*) is in scope, which means the code has no problem.
    > > But Comeau rejects the code. Is it correct or not?

    >
    > Seems to be a bug. Have you tried contacting Comeau?


    Here you and Rob go separate ways.
    Rob's answer looks more convincing, though.

    >
    > FWIW, Visual C++ 2003 gets it right. g++ v2.95.2 gets it right. g++
    > v3.2.2 gets it right. MIPSpro v7.4 gets it right. HP's aCC v3.50 gets
    > it right... I decided to stop at that point.


    Whoa.. You have quite many machines in your reach.
    Thank you for the information.

    --
    ES Kim
    ES Kim, Apr 15, 2005
    #4
  5. ES Kim

    ES Kim Guest

    "Rob Williscroft" <> wrote in message
    news:Xns9638DAD2CA827rtwfreenetREMOVEcouk@216.196.109.145...
    > ES Kim wrote in news:d3kocl$nfm$ in comp.lang.c++:
    >>
    > > I think foo
    > > IS a dependent name there and point of instantiation binding applies.

    >
    > foo( t ) (2) can only be bound to function's that were declared prior
    > to the defenition (body) of S<>:f(), only function's found by ADL
    > (Argument dependent Lookup) are allowed to bypass this rule.
    >
    > In this case its foo( int ) as that is the *only* foo available when
    > S<>::f() is parsed.
    >
    > > At that point, void foo(int*) is in scope,

    >
    > foo(int *) is an overload of foo(int) however it isn't found by ADL
    > as ADL isn't used when all paramiters are pure inbult types (int,
    > int * etc).
    >
    > For ADL to be used T would need to be declared in a different namespace
    > to S<>, in which case the compiler would use ADL to look for overloads
    > foo( convertible_from_T ) in T's namespace, whether or not they were
    > declared before the defenition of s<>::f().
    >
    > > which means the code has no
    > > problem. But Comeau rejects the code. Is it correct or not?
    > >

    >
    > Its correct an int * can't be converted to an int without a cast.


    Yes, now it makes sense. Some guy tried a slightly tweaked version.

    void foo(int);

    template<typename T>
    struct S
    {
    void f()
    {
    foo(1); // (1)
    T t;
    foo(t); // (2)
    }
    };

    class C {}; // modified
    void foo(C); // modified

    // <--- point of instantiation
    int main()
    {
    S<C> a; // modified
    a.f();
    }

    Now Comeau compiles clean, since 'C' is a user-defined name and ADL mechanism
    works according to your explanation.
    I remember I was helped with ADL from you months ago. Thank you again.

    --
    ES Kim
    ES Kim, Apr 15, 2005
    #5
    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. David
    Replies:
    2
    Views:
    276
    Michiel Salters
    May 13, 2004
  2. Replies:
    1
    Views:
    559
    Salt_Peter
    Dec 25, 2006
  3. Replies:
    4
    Views:
    327
  4. Alessandro [AkiRoss] Re
    Replies:
    3
    Views:
    422
    Michael Doubez
    May 13, 2009
  5. Saraswati lakki
    Replies:
    0
    Views:
    1,287
    Saraswati lakki
    Jan 6, 2012
Loading...

Share This Page