473,387 Members | 1,532 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

Question about ADL

(Message also posted to comp.std.c++)

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<int> 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
Jul 22 '05 #1
5 1487

<de***@cis.strath.ac.uk> wrote in message
news:20040429095020.2838f34e.de***@cis.strath.ac.u k...
(Message also posted to comp.std.c++)

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";};
A<T>::f() or this->f()

It has to do with the way non-dependent names are looked up -- they are not
looked up in dependent base classes but they still need to be looked up when
they are encountered. Using either of the techniques above, makes them
dependent names and hence delays the actual lookup till instantiation time.

Two phase lookup goes like this(roughly): In the first stage(while parsing),
non-dependent names are looked up using ordinary lookup rules (and ADL, if
needed). In the second phase (which happens when the templates are actually
instantiated), dependent qualified names are looked up.

};

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

You don't need the last ';'.

Regards,
Sumit.

Jul 22 '05 #2
> A<T>::f() or this->f()

Thanks, Sumit, for your comments. I realise that both of these approaches work - also qualifying with B<T> works: B<T>::f(). I suppose that this last example is the one that emphasises the reasons for my surprise most strongly. If class B were to include a function, void h(), then one could substitute h() for f() and get no compiler complaint. It seems as though every function call to a non-virtual method could be considered to be implicitly qualified with the class in which it is being used. It is very stange, to me, that the scope for looking up f() does not include the base class (as it did in earlier versions of the g++ compiler, at any rate).
It has to do with the way non-dependent names are looked up -- they are not
looked up in dependent base classes but they still need to be looked up when
they are encountered.


So this is the key point: "they are not looked up in dependent base classes". So earlier versions of g++ were incorrect in doing so?
int main()
{
B<int> b;
b.g();
};

You don't need the last ';'.


I know - but old habits die hard and it does no harm. Consider it a personal idiosynchratic signature on my code!

Cheers

Derek
Jul 22 '05 #3

<de***@cis.strath.ac.uk> wrote in message
news:20040429141930.353044a8.de***@cis.strath.ac.u k...
A<T>::f() or this->f()
Thanks, Sumit, for your comments. I realise that both of these approaches

work - also qualifying with B<T> works: B<T>::f(). I suppose that this last
example is the one that emphasises the reasons for my surprise most
strongly. If class B were to include a function, void h(), then one could
substitute h() for f() and get no compiler complaint. It seems as though
every function call to a non-virtual method could be considered to be
implicitly qualified with the class in which it is being used. It is very
stange, to me, that the scope for looking up f() does not include the base
class (as it did in earlier versions of the g++ compiler, at any rate).
Greetings Derek!

A<T>::f(), this->f(), B<T>::f() -- Any of these would make f() dependent.
Personally, I tend to prefer the first one since I find it most
reader-friendly. On your comment, "is very stange, to me, that the scope for
looking up f() does not include the base class": The is true of *dependent*
base classes. For example, consider the following:
#include <iostream>

class X {
public:
int f2(){return 45;}
};

template<typename T>
class B : public X {
T t;
public:
void g() {std::cout << f2() << '\n';}
};

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

Here X is a non-dependent base class.
In this case, the call the f2() works (you don't need to use this->f2() or
X::f2() ) perfectly since X is a non-dependent base.

So this is the key point: "they are not looked up in dependent base classes". So earlier versions of g++ were incorrect in doing so?

Yes. I just tried your code with g++ 3.2. You are right: it does not
complain when I feed it your original case. But from what you say in your
original posting, it looks like that version 3.4 has fixed that.
int main()
{
B<int> b;
b.g();
};

You don't need the last ';'.


I know - but old habits die hard and it does no harm. Consider it a

personal idiosynchratic signature on my code!

Ah! That's an truly original way of looking at it: a personal signature. :-)

Regards,
Sumit.
Jul 22 '05 #4
>>>>int main()
{
B<int> b;
b.g();
};
You don't need the last ';'.


I know - but old habits die hard and it does no harm. Consider it a


personal idiosynchratic signature on my code!

Ah! That's an truly original way of looking at it: a personal signature. :-)


I don't know about with functions, but gcc 3.4 now complains
about namespaces like the following:

namespace XX
{

}; // ERROR! BAD SEMI-COLON THINGY!

--
http://www.it-is-truth.org/
Jul 22 '05 #5
de***@cis.strath.ac.uk wrote in message news:<20040429095020.2838f34e.de***@cis.strath.ac. uk>...
(Message also posted to comp.std.c++)

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


I think that GCC 3.4.0 is correct to complain, because the compiler
cannot see a declaration of f() when it parses the code for class B.
c.f. section 14.6/1 of the Standard, which defines the types of names
that can be used within a template definition:
1) the name of the template itself, and names declared within it
2) names dependent on a template-parameter
3) names from visible scopes

the "naked" call to f() in the definition of class B does not meet any
of those criteria. Using the scope resolution operator (i.e.
A<T>::f() ) clears up this problem by making the declaration of f()
dependent on the template parameter T (c.f. 14.6.2.1/1).

HTH, Dave Moore
Jul 22 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Mohammed Mazid | last post by:
Can anyone please help me on how to move to the next and previous question? Here is a snippet of my code: Private Sub cmdNext_Click() End Sub Private Sub cmdPrevious_Click() showrecord
3
by: Stevey | last post by:
I have the following XML file... <?xml version="1.0"?> <animals> <animal> <name>Tiger</name> <questions> <question index="0">true</question> <question index="1">true</question> </questions>
7
by: nospam | last post by:
Ok, 3rd or is it the 4th time I have asked this question on Partial Types, so, since it seems to me that Partial Types is still in the design or development stages at Microsoft, I am going to ask...
3
by: Ekqvist Marko | last post by:
Hi, I have one Access database table including questions and answers. Now I need to give answer id automatically to questionID column. But I don't know how it is best (fastest) to do? table...
10
by: glenn | last post by:
I am use to programming in php and the way session and post vars are past from fields on one page through to the post page automatically where I can get to their values easily to write to a...
10
by: Rider | last post by:
Hi, simple(?) question about asp.net configuration.. I've installed ASP.NET 2.0 QuickStart Sample successfully. But, When I'm first start application the follow message shown. ========= Server...
53
by: Jeff | last post by:
In the function below, can size ever be 0 (zero)? char *clc_strdup(const char * CLC_RESTRICT s) { size_t size; char *p; clc_assert_not_null(clc_strdup, s); size = strlen(s) + 1;
56
by: spibou | last post by:
In the statement "a *= expression" is expression assumed to be parenthesized ? For example if I write "a *= b+c" is this the same as "a = a * (b+c)" or "a = a * b+c" ?
2
by: Allan Ebdrup | last post by:
Hi, I'm trying to render a Matrix question in my ASP.Net 2.0 page, A matrix question is a question where you have several options that can all be rated according to several possible ratings (from...
3
by: Zhang Weiwu | last post by:
Hello! I wrote this: ..required-question p:after { content: "*"; } Corresponding HTML: <div class="required-question"><p>Question Text</p><input /></div> <div...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.