argument dependent lookup

  • Follow


Hello.

#include <vector>
std::vector<int> v;
transform(v.begin(), v.end(), v.begin(), Delete_ptr);

This code compiles even though I forgot #include <algorithm> and using
std::transform;

Q1. I've been reading a little about Koenig Lookup in Exceptional C++ (Item
31) and argument dependent lookup in C++ Primer. Is this the explanation why
my code compiles?

Q2. A different compiler gives the error - 'transform:' identifier not
found, even with argument dependent lookup. Is this compiler incorrect?

Thank you,
Marlene


      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Marlene 4/8/2005 11:45:46 PM

"Marlene Miller" <marlenemiller@worldnet.att.net> �������/�������� �
�������� ���������:
news:lHz5e.541493$w62.513772@bgtnsc05-news.ops.worldnet.att.net...
> Hello.
>
> #include <vector>
> std::vector<int> v;
> transform(v.begin(), v.end(), v.begin(), Delete_ptr);
>
> This code compiles even though I forgot #include <algorithm> and using
> std::transform;
>
> Q1. I've been reading a little about Koenig Lookup in Exceptional C++
(Item
> 31) and argument dependent lookup in C++ Primer. Is this the explanation
why
> my code compiles?
>
> Q2. A different compiler gives the error - 'transform:' identifier not
> found, even with argument dependent lookup. Is this compiler incorrect?
>

A1)
         No, the reason isn't Koenig lookup.Koenig lookup means
         that the argument's associated namespace is considered
         when performing name lookup.But here,there would be no namespace
         to be associated with,because you haven't included the headers.
         In your case,my guess would be that the compiler vendors are allowed
to
         include additional headers if they think
         that they need them.What I mean is that your STL version probably
         includes <algorithm> in <vector>.You should still remember that
         although it works for your compiler,it's still not portable.
A2)
         No,because the standard doesn't specify the header that are allowed
to be included
         form other std headers.



      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply efim 4/9/2005 10:07:05 AM


"Marlene Miller" <marlenemiller@worldnet.att.net> wrote in message
news:lHz5e.541493$w62.513772@bgtnsc05-news.ops.worldnet.att.net...
Hello,
> #include <vector>
> std::vector<int> v;
> transform(v.begin(), v.end(), v.begin(), Delete_ptr);
>
> This code compiles even though I forgot #include <algorithm> and using
> std::transform;

This is by 'accident': nothing prevents a standard header (e.g. <vector>)
from including any other standard header (e.g. <algorithm>). Library
implementers are free to have such (undocumented) internal dependencies.

> Q1. I've been reading a little about Koenig Lookup in Exceptional C++
> (Item
> 31) and argument dependent lookup in C++ Primer. Is this the explanation
> why
> my code compiles?

No.
Argument-dependent lookup can only overcome "namespace barriers".
It cannot find a function whose declaration has not previously been
seen during a unit's translation.

> Q2. A different compiler gives the error - 'transform:' identifier not
> found, even with argument dependent lookup. Is this compiler incorrect?

No - the code is.
For a program to be portable, it has to explicitly include all the
standard library headers that it uses.
This does sometimes create protability challenges because of
differences between standard library implementations.

Cheers,
Ivan
-- 
http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form



      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Ivan 4/9/2005 10:08:34 AM

"Marlene Miller" <marlenemiller@worldnet.att.net> writes:

> #include <vector>
> std::vector<int> v;
> transform(v.begin(), v.end(), v.begin(), Delete_ptr);
>
> This code compiles even though I forgot #include <algorithm> and using
> std::transform;
>
> Q1. I've been reading a little about Koenig Lookup in Exceptional
> C++ (Item 31) and argument dependent lookup in C++ Primer. Is this
> the explanation why my code compiles?

[Also, <vector> seems to #include <algorithm>.]


> Q2. A different compiler gives the error - 'transform:' identifier not
> found, even with argument dependent lookup. Is this compiler incorrect?

Not necessarily.

The most like reason is that on this implementation, v.begin()'s type
is int *, which means that argument dependent lookup does not look
into namespace std. On the other implementation, v.begin()'s type
seems to be a class type that belongs to namespace std.


For portable code, you therefore have to explicitly tell the compiler
to look in namespace std, by using "using" (SCNR :-) ) or by
qualifying transform.

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Thomas 4/9/2005 10:15:04 AM

On 8 Apr 2005 19:45:46 -0400, Marlene Miller  
<marlenemiller@worldnet.att.net> wrote:

> #include <vector>
> std::vector<int> v;
> transform(v.begin(), v.end(), v.begin(), Delete_ptr);
>
> This code compiles even though I forgot #include <algorithm>

It's just your standard library implementation happens to include  
<algorithm> header somewhere in <vector> header.

> and using std::transform;
>
> Q1. I've been reading a little about Koenig Lookup in Exceptional  
> C++ (Item
> 31) and argument dependent lookup in C++ Primer. Is this the explanation  
> why
> my code compiles?
>
> Q2. A different compiler gives the error - 'transform:' identifier not
> found, even with argument dependent lookup. Is this compiler incorrect?

Unqualified transform (i.e. without std::) works when the iterators  
returned by std::vector<>::begin/end() are implemented as classes in std  
namespace, so std::transform is found by argument dependent lookup. If  
vector's iterators are just typedefs to plain pointers, the argument  
dependent lookup won't find std::transform, because built-it types have no  
associated namespace but the global.

It's not reasonable to assume how vector's iterators are implemented, and  
in fact some libraries (like STLPort) use different types of iterators in  
debug and release builds. In portable code if none of transform (the same  
applies for other algorithms) call arguments comes from namespace std you  
have to qualify transform with std:: or make transform name accessible via  
using declaration (using std::transform) or using directive (using  
namespace std).

-- 
Maxim Yegorushkin

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Maxim 4/9/2005 10:50:00 PM

marlenemiller@worldnet.att.net (Marlene Miller) wrote (abridged):
> #include <vector>
> std::vector<int> v;
> transform(v.begin(), v.end(), v.begin(), Delete_ptr);
> 
> This code compiles even though I forgot #include <algorithm> and using
> std::transform;
> 
> Q1. I've been reading a little about Koenig Lookup in Exceptional C++ 
> (Item 31) and argument dependent lookup in C++ Primer. Is this the 
> explanation why my code compiles?

It's half the reason - it's why you didn't need std:: in front of 
transform. This implementation must use a class for std::vector::iterator.

It doesn't explain how std::transform got declared in your compilation 
unit despite not having an explicit #include<algorithm>. That is because 
this implementation must have an equivalent include in its definition of 
<vector>.

Both of these are permitted in, but not required of, conforming C++ 
implementations.


> Q2. A different compiler gives the error - 'transform:' identifier not
> found, even with argument dependent lookup. Is this compiler incorrect?

No. The other compile might use (int *) as the iterator type, and/or its 
<vector> may not #include <algorithm>.

Your code relies on two accidents of implementation. It's not guaranteed 
to compile.

-- Dave Harris, Nottingham, UK.

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply brangdon 4/9/2005 10:54:56 PM

Thank you to all. Very helpful explanations.

On further investigation, I see that the vendor's STL library does #include
<algorithm> in the <vector> header file, and declares using std::transform
in the <algorithm> header file.




      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Marlene 4/10/2005 8:56:02 AM

"Marlene Miller" <marlenemiller@worldnet.att.net> wrote in
message
news:Br06e.59898$cg1.4065@bgtnsc04-news.ops.worldnet.att.net...
> On further investigation, I see that the vendor's STL library
does #include
> <algorithm> in the <vector> header file,

That's ok.

> and declares using std::transform
> in the <algorithm> header file.

In the global namespace? That can't be right. I'm sure standard
headers must not introduce arbitrary names into the global
namespace. Perhaps the "using std::transform" is not in the
global namespace, and ADL is involved (as suggested)?

Yechezkel Mett



      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Yechezkel 4/12/2005 8:52:22 PM

> > and declares using std::transform
> > in the <algorithm> header file.
>
> In the global namespace? That can't be right. I'm sure standard
> headers must not introduce arbitrary names into the global
> namespace. Perhaps the "using std::transform" is not in the
> global namespace, and ADL is involved (as suggested)?
>
> Yechezkel Mett

Oh, I made a mistake. The include file "algorithm" does not declare
using::transform.  (The include file "algorithm.h" includes <algorithm>
followed by a long list of using declarations.) The vector iterator is a
class.

// file vector
class vector<bool, Allocator>
{
//...
   class  iterator;        // random access
}
#include <algorithm>
#include <iterator>

//file iterator
struct iterator
{
//...
};


      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Marlene 4/13/2005 6:52:26 AM

8 Replies
127 Views

(page loaded in 0.405 seconds)

Similiar Articles:








7/23/2012 7:46:59 PM


Reply: