C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Question about ADL

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language, library and standards
View previous topic :: View next topic  
Author Message
Derek Long
Guest





PostPosted: Wed Apr 28, 2004 3:57 pm    Post subject: Question about ADL Reply with quote



I have just been experimenting with g++ 3.4 and code that I thought was
compliant has raised compiler problems. Basically, if we have the
following code:

#include <iostream>

using std::cout;

template<typename T>
class A {
public:
T f() {return T();};
};

template<typename T>
class B : public A<T> {
public:
void g() {cout << f() << "n";};
};

int main()
{
B b.g();
};


I would have expected the call to f() in g() to be OK. However, it isn't
for g++ 3.4:

checker.cc: In member function `void B<T>::g()':
checker.cc:14: error: there are no arguments to `f' that depend on a
template parameter, so a declaration of `f' must be available
checker.cc:14: error: (if you use `-fpermissive', G++ will accept your
code, but allowing the use of an undeclared name is deprecated)

Replacing f() with A<T>::f() will fix it. But is it a valid error, or is
g++ 3.4 wrong?

Thanks for any insights anyone can offer on this.

Derek

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]

Back to top
Alberto Barbati
Guest





PostPosted: Fri Apr 30, 2004 3:15 am    Post subject: Re: Question about ADL Reply with quote



Derek Long wrote:
Quote:
I have just been experimenting with g++ 3.4 and code that I thought was
compliant has raised compiler problems. Basically, if we have the
following code:
snip

This has nothing to do with ADL which stands for "Argument Dependent
Lookup". All functions in your example take no argument, so ADL is never
involved. Maybe you are confusing ADL with the so called "two-phase name
lookup", which is the real issue here.

By the way, a very similar question has been discussed on this forum
just a few days ago, under the subject 'Rationale for "this->" in
template derived classes?'.

Quote:
I would have expected the call to f() in g() to be OK. However, it isn't
for g++ 3.4:

g++ is right. An unqualified non-dependent name must be bound at the
point of definition (phase one) and the base template class A<T> is not
searched because its definition is still unknown. Yes, it's unknown!
Even if you just gave the definition for the generic template of A<T>,
there may be specialization not yet known at the point of definition of
B<T>. See the aforementioned discussion thread for details.

Quote:
checker.cc: In member function `void B<T>::g()':
checker.cc:14: error: there are no arguments to `f' that depend on a
template parameter, so a declaration of `f' must be available

see? as there are no arguments to f, the compiler is saying that it
can't use ADL.

Quote:
Replacing f() with A<T>::f() will fix it.

Sure, as the name is now qualified and dependent on T, it will be bound
at the point of instantiation (phase two). In phase two, the compiler
knows the exact type that replaces T and so it can select the right
specialization of A<T> (specializing A<T> after this point makes the
program ill-formed).

Another, more elegant, way to make the name dependent is by writing
this->f().

Alberto

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Ben Hutchings
Guest





PostPosted: Fri Apr 30, 2004 3:15 am    Post subject: Re: Question about ADL Reply with quote



Derek Long wrote:
Quote:
I have just been experimenting with g++ 3.4 and code that I thought was
compliant has raised compiler problems. Basically, if we have the
following code:
snip
template<typename T
class A {
public:
T f() {return T();};
};

template class B : public A public:
void g() {cout << f() << "n";};
};
snip
I would have expected the call to f() in g() to be OK. However, it isn't
for g++ 3.4:

checker.cc: In member function `void B checker.cc:14: error: there are no arguments to `f' that depend on a
template parameter, so a declaration of `f' must be available
checker.cc:14: error: (if you use `-fpermissive', G++ will accept your
code, but allowing the use of an undeclared name is deprecated)

Replacing f() with A<T>::f() will fix it. But is it a valid error, or is
g++ 3.4 wrong?

This has nothing to do with ADL. It is a result of the switch to
two-phase name lookup required by the standard.

The problem results from these rules:
- Names used in templates are classified as dependent or non-dependent
(on the template parameters). Non-dependent names are looked up
when the template is defined whereas dependent names are looked up
when the template is instantiated. (Old template implementations
defer all name lookup until instaniation.)
- Non-dependent name lookup does not look in dependent base classes
because their definitions are not necessarily available. (There
may be specialisations to follow.)
- Unqualified names are generally classified as non-dependent.

Where a name is intended to be looked up in a dependent base class,
it should be made dependent by qualifying it with "this->" or with
the scope operator and base class name.

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Thorsten Ottosen
Guest





PostPosted: Fri Apr 30, 2004 5:47 am    Post subject: Re: Question about ADL Reply with quote

"Derek Long" <Derek.Long (AT) cis (DOT) strath.ac.uk> wrote


[snip]

<typename T>
Quote:
class B : public A<T> {
public:
void g() {cout << f() << "n";};
};

int main()
{
B b.g();
};


I would have expected the call to f() in g() to be OK. However, it isn't
for g++ 3.4:

It has to do with two-phase lookup. When you have a dependent base class
(a class which depends on a template parameter), you need to say either

1. A<T>::f() // no virtual dispatch
2. this->f(); // virtual dispatch if f() is vitual

br

Thorsten


---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language, library and standards All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.