 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Derek Long Guest
|
Posted: Wed Apr 28, 2004 3:57 pm Post subject: Question about ADL |
|
|
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
|
Posted: Fri Apr 30, 2004 3:15 am Post subject: Re: Question about ADL |
|
|
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
|
Posted: Fri Apr 30, 2004 3:15 am Post subject: Re: Question about ADL |
|
|
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
|
Posted: Fri Apr 30, 2004 5:47 am Post subject: Re: Question about ADL |
|
|
"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 |
|
 |
|
|
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
|
|