point of definition or instantiation of a template

E

ES Kim

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?
 
V

Victor Bazarov

ES said:
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
 
R

Rob Williscroft

ES Kim wrote in 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 said:
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 said:
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.
 
E

ES Kim

Victor Bazarov said:
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.
 
E

ES Kim

Rob Williscroft said:
ES Kim wrote in news:[email protected] in comp.lang.c++:

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


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


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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top