By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,233 Members | 1,939 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,233 IT Pros & Developers. It's quick & easy.

point of definition or instantiation of a template

P: n/a
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
Jul 23 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a
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
Jul 23 '05 #2

P: n/a
ES Kim wrote in news:d3**********@news1.kornet.net 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/
Jul 23 '05 #3

P: n/a
"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:om*******************@newsread1.mlpsca01.us.t o.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
Jul 23 '05 #4

P: n/a
"Rob Williscroft" <rt*@freenet.co.uk> wrote in message
news:Xn**********************************@216.196. 109.145...
ES Kim wrote in news:d3**********@news1.kornet.net 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
Jul 23 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.