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