Topic: Koenig lookup and stream manipulators
Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1998/12/11 Raw View
Nathan Myers wrote:
>
> <dietmar.kuehl@claas-solutions.de> wrote:
> >Koenig lookup helps to find functions in namespaces: If some object
> >from some namespace is used as a function argument, this function is
> >looked up, if it is not found otherwise, in the namespace of the object.
>
> This isn't quite accurate. The function name is looked up in the
> namespace of the argument type regardless of whether it's found
> anywhere else, and all the functions found by whatever means are
> overloaded and the best match is chosen.
>
> >Recently I
> >came across an even cooler use in conjunction with IOStreams:
> >
> > using std::cout;
> > cout << "hello, world" << endl;
> >
> >Now the idea is this: We already say which namespace 'cout' is in and
> >Koenig lookup will thus find 'endl'. The reasoning is this: Koenig
> >lookup extends the namespaces where names are looked for.
>
> Sorry. std::endl is a function, but at the point where "endl" is
> mentioned, here, it has no arguments to specify namespaces to look
> in, or even to suggest to the compiler that it is in fact a function.
>
> Perhaps the compiler should try looking up all unbound names
> in the namespaces where it finds other names used in the same
> expression? I wouldn't ask for that.
That would be bad indeed. However, one could imagine that
for functions where _some_ arguments are found, Koenig lookup
for the function is done using only the known objects as
"namespace source". Then in a second step, for each function
found by this "incomplete Koenig lookup", the other (not yet
found) parameters are looked up in the scope of the function.
Only if there's a single function scope from which all
remaining parameterrs can be found, the function is considered
a valid candidate. Then normal type matching proceeds, but for
the "dependent" parameters, only those objects are considered
which are found through the appropriate function. Note that
other parts of the expression are not affected.
Example:
namespace A
{
class X {};
int x;
int y;
int z;
B::Y w;
}
namespace B
{
class Y {};
char* y;
Y z;
}
namespace A
{
void f(X, B::Y, int);
}
namespace B
{
void f(A::X, Y, Y);
}
void f()
{
A::X a;
B::Y b;
f(a, b, x); // Ok: A::f
f(a, b, y); // Ok: Considered set: (A::f, A::x; B::f, B::x)
// However, the second alternative fails due to
// wrong argument type (no conversion char*->Y)
f(a, b, z); // Error: Abiguity between A::f(a, b, A::z) and
// B::f(a, b, B::z)
f(a, b, w); // Error: A::f can't get a B::Y as last argument, and
// there's no B::w object. Note that despite
// the call A::f(a, b, B::z) would be legal,
// it is not considered.
}
There has to be a rule for nested expressions. The rule I'd
say is that this lookup extension does only directly extend
to the toplevel symbol of the next expression (i.e. if it's
a function call, only the function name lookup is affected).
Deeper nested expressions can only be affected indirectly,
as in the following example:
namespace A
{
class X {};
void f(X, int);
int g(int);
int x;
}
namespace B
{
class X {};
void f(X, int);
int g(int);
int x;
}
int h(int);
void foo()
{
A::X a;
B::X b;
f(a, g(x)); // f is A::f, therefore g is A::g, therefore x is A::x
f(b, g(x)); // f is B::f, therefore g is B::g, therefore x is B::x
f(a, h(x)); // Error: x undefined: "reverse lookup" doesn't apply to
// indirect arguments
}
Of course, outer expressions can be affected through the return type;
however, this is true for Koenig lookup as well.
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: dietmar.kuehl@claas-solutions.de
Date: 1998/12/09 Raw View
Hi,
Koenig lookup helps to find functions in namespaces: If some object from some
namespace is used as a function argument, this function is looked up, if it is
not found otherwise, in the namespace of the object. That's cool. Recently I
came across an even cooler use in conjunction with IOStreams:
using std::cout;
cout << "hello, world" << endl;
Now the idea is this: We already say which namespace 'cout' is in and Koenig
lookup will thus find 'endl'. The reasoning is this: Koenig lookup extends
the namespaces where names are looked for. Since one argument to
'operator<<()' is known to be namespace 'std', name lookup is extended to
namespace 'std'. There, 'endl' is found. Finally, 'operator<<()' is looked
up, also in namespace 'std' (the latter part is natural and actually no
question at all: The first argument is clearly in namespace 'std', thus is
looked for an 'operator<<()' there).
Of course, it would be nice if this case would be covered by the standard.
The question, however, is: Is 'endl' found? Or is it necessary to specify the
namespace? I think it is necessary to specify the namespace for 'endl'
because Koenig lookup applies only to functions being looked up depending on
its arguments. Of course, 'endl' actually is a function but at the time it is
to be found it is only an argument (there is no need to specify the namespace
for 'endl' in this expression: 'endl(std::cout);' but this is a completely
different case...).
Does anybody know what is right? (Don't ask the compiler: All compilers I
tried give me the answer that the namespace specification is needed for
'endl' but I don't trust compilers, especially with respect to relatively new
features). -- <mailto:dietmar.kuehl@claas-solutions.de> homepage:
<http://www.informatik.uni-konstanz.de/~kuehl>
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1998/12/10 Raw View
<dietmar.kuehl@claas-solutions.de> wrote:
>Koenig lookup helps to find functions in namespaces: If some object
>from some namespace is used as a function argument, this function is
>looked up, if it is not found otherwise, in the namespace of the object.
This isn't quite accurate. The function name is looked up in the
namespace of the argument type regardless of whether it's found
anywhere else, and all the functions found by whatever means are
overloaded and the best match is chosen.
>Recently I
>came across an even cooler use in conjunction with IOStreams:
>
> using std::cout;
> cout << "hello, world" << endl;
>
>Now the idea is this: We already say which namespace 'cout' is in and
>Koenig lookup will thus find 'endl'. The reasoning is this: Koenig
>lookup extends the namespaces where names are looked for.
Sorry. std::endl is a function, but at the point where "endl" is
mentioned, here, it has no arguments to specify namespaces to look
in, or even to suggest to the compiler that it is in fact a function.
Perhaps the compiler should try looking up all unbound names
in the namespaces where it finds other names used in the same
expression? I wouldn't ask for that.
--
Nathan Myers
ncm@nospam.cantrip.org http://www.cantrip.org/
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]