Topic: Dependent name lookup: unclear wording in the standard?


Author: xleobx@qmailcomq.com
Date: Thu, 29 May 2003 04:48:31 +0000 (UTC)
Raw View
I've got into an argument with an anonymous at Comeau over the following:

#include <map>

template <class T> class Map : public std::map<int , T*> {
public:
        T* Find (int val) {
          typename std::map<int,T*>::iterator it = find (val);
          if (it == end()) return 0;
          return it->second;
        }
};

The Comeau compiler says that "find" and "end" are undefined, whereas
the standard (14.6.2p4) says:

<<If a base class is a dependent type,
a member of that class cannot _hide_ (emphasis mine - LB) a name declared
within a template, or a name from the template's enclosing scopes.>>

It this example, there is no find() or end() in global scope, so there is
nothing to hide or not to hide. The standard does not say that members
of the dependent base class must not be visible at all, does it?

To clarify the intent of the standard, the example in 14.6.2p4 should
include a unique name in struct A and demonstrate its usage in Y<A>, e.g.:

struct A {
 struct B { /* ... */ };
 int a, z;
 int Y;
};

int a;

template <class T> struct Y : T {
 struct B { /* ... */ };
 B b;    // The B defined in Y
 void f(int i) { a = i; } // ::a
 Y* p;    // Y<T>
 void g(int i) { z = i; } // What happens? When? Why?
};

Y<A> ya;

If the intent of the standard is to disallow unqualified lookups
into dependent base classes altogether, it is better worded in a
more straightforward way.
If not, somebody please tell Comeau. :-)

Thanks,
 Leo

---
[ 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                       ]





Author: hyrosen@mail.com (Hyman Rosen)
Date: Thu, 29 May 2003 15:52:35 +0000 (UTC)
Raw View
xleobx@qmailcomq.com wrote:
> If the intent of the standard is to disallow unqualified lookups
> into dependent base classes altogether, it is better worded in a
> more straightforward way.

You mean like 14.6.2/3?
     In the definition of a class template ... if a base class
     of this template depends on a template-parameter, the base
     class scope is not examined during name lookup until the
     class template is instantiated.

---
[ 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                       ]





Author: bop2@telia.com ("Bo Persson")
Date: Thu, 29 May 2003 15:54:40 +0000 (UTC)
Raw View
<xleobx@qmailcomq.com> skrev i meddelandet
news:ml9Ba.21141$io.364561@iad-read.news.verio.net...
>
> I've got into an argument with an anonymous at Comeau over the following:
>
> #include <map>
>
> template <class T> class Map : public std::map<int , T*> {
> public:
>         T* Find (int val) {
>           typename std::map<int,T*>::iterator it = find (val);
>           if (it == end()) return 0;
>           return it->second;
>         }
> };
>
> The Comeau compiler says that "find" and "end" are undefined, whereas
> the standard (14.6.2p4) says:
>
> <<If a base class is a dependent type,
> a member of that class cannot _hide_ (emphasis mine - LB) a name declared
> within a template, or a name from the template's enclosing scopes.>>
>
> It this example, there is no find() or end() in global scope, so there is
> nothing to hide or not to hide. The standard does not say that members
> of the dependent base class must not be visible at all, does it?

I think that is the intention, yes.

What if you later add a specialization std::map<int, sometype*>, without
defining find() in it?

What if you have a global find() function, and just some of the base
specializations also have one? Should the compiler choose differently or be
consistent and complain? I prefer consistency. :-)


Bo Persson
bop2@telia.com

---
[ 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                       ]





Author: do-not-spam-ben.hutchings@businesswebsoftware.com (Ben Hutchings)
Date: Thu, 29 May 2003 15:55:57 +0000 (UTC)
Raw View
In article <ml9Ba.21141$io.364561@iad-read.news.verio.net>,
xleobx@qmailcomq.com wrote:
>
> I've got into an argument with an anonymous at Comeau over the following:
>
> #include <map>
>
> template <class T> class Map : public std::map<int , T*> {
> public:
>         T* Find (int val) {
>           typename std::map<int,T*>::iterator it = find (val);
>           if (it == end()) return 0;
>           return it->second;
>         }
> };
>
> The Comeau compiler says that "find" and "end" are undefined, whereas
> the standard (14.6.2p4) says:
>
><<If a base class is a dependent type,
> a member of that class cannot _hide_ (emphasis mine - LB) a name declared
> within a template, or a name from the template's enclosing scopes.>>
>
> It this example, there is no find() or end() in global scope, so there is
> nothing to hide or not to hide. The standard does not say that members
> of the dependent base class must not be visible at all, does it?
<snip>

Look one paragraph further up (14.6.2p3):

   "...if a base class of this template depends on a template-parameter,
    the base class scope is not examined during name lookup until the
    class template is instantiated."

Since find and end are not dependent names they must be looked up in the
first phase, but the base class scope is not examined until the second
phase.

You can use "this->" in front of them to make them dependent names
(14.6.2.2p1-2).

---
[ 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                       ]





Author: xleobx@qmailcomq.com
Date: Fri, 30 May 2003 00:22:45 +0000 (UTC)
Raw View
xleobx@qmailcomq.com wrote:

> The Comeau compiler says that "find" and "end" are undefined, whereas
> the standard (14.6.2p4) says:

> <<If a base class is a dependent type,
> a member of that class cannot _hide_ (emphasis mine - LB) a name declared
> within a template, or a name from the template's enclosing scopes.>>


I have to apologize. While looking for answers for my question I got
to a page at anubis.dkuug.dk from which the access to the defect report
lists was password-protected (I forgot the URL, alas).
Since then I've found DR 213 that answers my
question perfectly: the wording of both 14.6.2p3 and 14.6.2p4 is
corrected as to eliminate the ambiguity and make the Comeau compiler
correct.

What makes things confusing is that every newer compiler has different
notion of "default" mode, "strict" mode, "relaxed" mode etc. wrt
all kinds of dependent name lookup.

 Leo

---
[ 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                       ]





Author: algrant@myrealbox.com (Al Grant)
Date: Fri, 30 May 2003 18:15:26 +0000 (UTC)
Raw View
do-not-spam-ben.hutchings@businesswebsoftware.com (Ben Hutchings) wrote in message news:<slrnbdbm03.150.do-not-spam-ben.hutchings@tin.bwsint.com>...
> You can use "this->" in front of them to make them dependent names
> (14.6.2.2p1-2).

I'm not sure this is anything to do with dependent names - prepending
"this->" works by forcibly introducing the base class scopes.
If making the name dependent was enough, then the function in question
would be found if it had a dependent parameter - this is not (I believe)
the rule followed by Comeau, though it does appear to be the rule
followed by HP aCC.  (Incidentally, aCC gives excellent diagnostics
here, referencing 14.6.2 and suggesting the appropriate code change.)

See attached sample program:

  Comeau (I think) would print "outer outer" though it is worth
    trying the "--no_dep_name" option here.
  HP aCC prints "outer inner".
  g++ 3.2.1 and VC++ 6.0 print "inner inner".

#include <stdio.h>

template<class T> struct B {
  void link(void *) { printf("inner\n"); }
};

void link(int *) { printf("outer\n"); }

template<class T> struct X: B<T> {
  void f(T *p) {
    link(0);
    link(p);
  }
};

int main() {
  X<int> c;
  c.f(0);
  return 0;
}

---
[ 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                       ]





Author: comeau@panix.com (Greg Comeau)
Date: Fri, 30 May 2003 23:27:37 +0000 (UTC)
Raw View
In article <EatBa.21455$io.366247@iad-read.news.verio.net>,
 <xleobx@qmailcomq.com> wrote:
>xleobx@qmailcomq.com wrote:
>> The Comeau compiler says that "find" and "end" are undefined, whereas
>> the standard (14.6.2p4) says:
>
>> <<If a base class is a dependent type,
>> a member of that class cannot _hide_ (emphasis mine - LB) a name declared
>> within a template, or a name from the template's enclosing scopes.>>
>
>I have to apologize. While looking for answers for my question I got
>to a page at anubis.dkuug.dk from which the access to the defect report
>lists was password-protected (I forgot the URL, alas).

If it's disabled for some reason, you can also try

  http://www.comeaucomputing.com/iso

>Since then I've found DR 213 that answers my
>question perfectly: the wording of both 14.6.2p3 and 14.6.2p4 is
>corrected as to eliminate the ambiguity and make the Comeau compiler
>correct.

Compounding things is that the whole general notion is still foreign
to many people, hence making issues such as this "surprising".

>What makes things confusing is that every newer compiler has different
>notion of "default" mode, "strict" mode, "relaxed" mode etc. wrt
>all kinds of dependent name lookup.

True, but such is a necessary evil.   Standard C++ doesn't,
can't and shouldn't cut it by itself so things need to be
flexible enough "to be useful".  But sure, it's not something
to necessarily be rejoying about, rather just content. :)
--
Greg Comeau/ 4.3.0.1: FULL CORE LANGUAGE, INCLUDING TC1
Comeau C/C++ ONLINE ==>     http://www.comeaucomputing.com/tryitout
World Class Compilers:  Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?

---
[ 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                       ]





Author: llewelly.at@xmission.dot.com (LLeweLLyn)
Date: Mon, 2 Jun 2003 01:03:00 +0000 (UTC)
Raw View
comeau@panix.com (Greg Comeau) writes:

> In article <EatBa.21455$io.366247@iad-read.news.verio.net>,
>  <xleobx@qmailcomq.com> wrote:
> >xleobx@qmailcomq.com wrote:
> >> The Comeau compiler says that "find" and "end" are undefined, whereas
> >> the standard (14.6.2p4) says:
> >
> >> <<If a base class is a dependent type,
> >> a member of that class cannot _hide_ (emphasis mine - LB) a name declared
> >> within a template, or a name from the template's enclosing scopes.>>
> >
> >I have to apologize. While looking for answers for my question I got
> >to a page at anubis.dkuug.dk from which the access to the defect report
> >lists was password-protected (I forgot the URL, alas).
[snip]

Probably you accidently clicked on the link that leads to the relevant
    section of the standard - those are password-protected due to ISO
    licensing rules about the standard. I do that all the time.


---
[ 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                       ]