(e-mail address removed) writes:
[...]
| > | There is a statement to the effect that "using-derectives are
| > | ingored in any namspace, including X, directly containing one or
| > | more declarations of m". If there is a toupper declared in :: (the
| > | standard forbids it, but all of the implementations I know do have
| > | one), then the using-directives in :: should be ignored. Which
| > | would make this code work. But it wouldn't work if the code,
| > | including the using directive, where in another namespace.
|
| > The executive summary is that if you write X::m, then any actual
| > declaration of "m" in "X" hides any other declarations that would have
| > been found by searching namespaces nominated, directly or indirectly,
| > in using declarations reachable from X. If no actually declaration
| > for "m" is made in "X", then the result of the name lookup will be
| > that of applying the rule recursively to the nominated namespaces.
|
| In sum, what I had intuitively expected (and what the compilers I use
| seem to implement). So why did the other posters say that "using
| namespace std" meant that ::toupper would find a toupper in std::.
I cannot speak for them and I hope they will clarify hat they meant.
And to tell the truth, I've lost most of those postings.
| But wait a minute. If I say explicitly that the only toupper that I
| want considered is the one in global namespace (e.g. ::toupper), and
| there isn't one in global namespace, the compiler will look elsewhere?
Yes. This is called in TC++PL3 "namespace composition" -- you trick
people into thinking that the "m" they're referring to in X::m comes
from your "X", whereas you may have just "stolen" it through
using-directives. E.g.
namespace N {
int m;
};
namespace X {
using namespace N; // compose X with N
}
int main()
{
return X::m; // finds N::m;
}
| That doesn't sound intuitively right -- I would expect an error.
I guess, it depends on how you look at the "::".
A view is that it is a scope resolution operator, i.e. it
disambiguates when there is a scope problem -- either there is no
visible declaration or there are too many visible declarations from
different scopes.
| > | This is all getting a bit beyond me. What I do know is that the
| > | compilers I have (Sun CC 5.1 and g++ 3.4.0) do NOT treat tolower and
| > | toupper as ambiguous here, even if I include <locale> (so that there
| > | are any number of toupper and tolower functions available). Whereas
| > | they do if I leave the :: out. So whatever the standard says...
|
| > because the declaration of ::toupper "hides" other declarations for
| > toupper in the used namespace std.
|
| Except that, of course, if the libraries were conform, there wouldn't
| have been a ::toupper in global namespace
.
Yes, but you (James) won't quibble me on that; right?
| Anyhow, I still contend that the only "correct" solution using transform
| involves something like:
| boost::bind( (char (*)(char, std::locale const&))&std::toupper,
| _1, std::locale() )
I really do dislike the cast notation in front of std::toupper. It is
not a cast, it is an abuse of notation (manual overload resolution).
People should not be tricked into thinking that someone is doing a
weird cast from std::toupper; let's sequester cast notations to cast.