Cases where I miss C++ 'using'
Bill Baxter
wbaxter at gmail.com
Mon Nov 6 12:45:59 PST 2006
In C++ 'using' can be like a D alias but with the target name implied.
E.g.
using Namespace::Class;
is like
alias Module.Class Class;
I find I'm using the latter construct pretty often, and it just looks
redundant compared to the equivalent in C++. If not a new 'using'
keyword, perhaps we could allow this?:
alias some.package.module;
or this
alias some.package.module .; // unix 'ln -s' syntax!
as a synonym for
alias some.package.module module;
If the thing being aliased has no dots,
alias string;
then it would be an error (just like "alias x x" is an error).
--
Another use of 'using' in C++ is, within the current block scope, to
bring every symbol in a namespace into the name table. E.g.
using namespace std;
makes std::string, std::vector, etc, all accessible without the std::
prefix.
This is quite similar to what with(std){...} would do, except 'using'
does it in the _current_ block scope rather than requiring you create a
new block scope. I find 'with' to be quite handy, but sometimes the
scope and extra nesting level are annoying, and it gets ugly if you want
to 'with' two or more things simultaneously. For example, say you want
to use std.math and std.string in one function (but don't want them
polluting your namespace elsewhere):
static import std.math;
static import std.string;
...
void do_something()
{
with(std.math) {
with(std.string) {
str = format("%f <= %f", fmin(a,b), fmax(a,b));
...
...
}
}
}
As an alternative to that, an alias-like "with declaration" would be handy:
void do_something()
{
with std.math, std.string;
str = format("%f <= %f", fmin(a,b), fmax(a,b));
...
...
}
It's basically the same as 'import' (in fact "with m=std.math" would
make sense too), except unlike import, it can be used anywhere, and not
just at the top-level scope, and it doesn't actually import anything
new, just gives new names to existing imported symbols. For that reason
it is probably a bad idea to use the 'import' keyword for this
functionality.
Like in C++ the compiler can complain if there are some symbols that
overlap. Though I'd prefer it just use a 'last one wins' rule, which
would be more equivalent to the nested 'with statements' case. Anyway,
I use that sort of pattern a lot in C++ (putting 'using' statements
within functions or classes or individual scopes). It's just good
programming practice to minimize namepspace pollution as much as possible.
--
Finally I wish there were some way to bring all the values in an *enum*
into the current name resolution scope. For example:
enum Buttons {
Left,
Right,
Middle
}
with(Buttons) { // doesn't work!
x = Left|Middle
}
alias Buttons B;
y = B.Left | B.Middle; // ok, but not as nice looking
--bb
More information about the Digitalmars-d
mailing list