Is there any good reason why C++ namespaces are "closed" in D?
Atila Neves
atila.neves at gmail.com
Mon Aug 6 15:49:00 UTC 2018
On Friday, 3 August 2018 at 21:49:53 UTC, Walter Bright wrote:
> On 8/3/2018 3:58 AM, Atila Neves wrote:
>> I would only be able to alias a nested namespace once, since
>> the code below obviously won't work:
>>
>> mixin CppNamespace0!() x;
>> alias chrono = x.std.chrono;
>> mixin CppNamespace1!() y;
>> alias chrono = y.std.chrono;
>
> Try this:
>
>
> mixin template X() { // boilerplate prefix
>
> extern (C++, std) extern(C++, chrono) int foo(); //
> original line
>
> } mixin X!() x; alias foo = x.std.chrono.foo; //
> boilerplate suffix
That doesn't solve the problem at all. I was toying with being
able to have a nested namespace be an alias in a module. I can't
realias chrono after the first `alias chrono = `, nor can I alias
it to the different `chrono`s in all the different template
mixins.
>> I considered for a while whether or not this would be truly
>> bad, and the more I think about it the more convinced I am
>> that Manu is right and there should be _no_ scoping whatsoever
>> in D regarding C++ namespaces. We have packages and modules,
>> we can use those to put the C++ functions we declare in
>> whatever hierarchy we want.
>
> I am puzzled. With:
>
> namespace std {
> namespace chrono {
> void foo();
> }
> }
>
> namespace std {
> namespace chrono {
> void bar();
> }
> }
>
> you have stated that it is impractical for your translator to
> rewrite this as:
>
> namespace std {
> namespace chrono {
> void foo();
> void bar();
> }
> }
>
> Ok, I get that. But it is practical to rewrite it as:
>
> module std.chrono;
> void foo();
> void bar();
>
> ?
I don't understand what your question has to do with what you
quoted. What I'm trying to say is that I think `extern(C++,
foo.bar)` should NOT introduce a scope in D in any way, shape, or
form. The D module/import/overload system should have no idea of
what `foo` or `foo.bar` are - they don't exist.
>
> > I mean `std` should never be part of the fully qualified name
> of, for
> > instance, `core.stdcpp.exception.std.bad_exception`. It
> should just
> > be `core.stdcpp.exception.bad_exception` instead.
>
> C++ recognizes that, too, which is why it has "using"
> declarations. D has the equivalent thing, "alias".
>
> You can do things like:
>
> import std = core.stdcpp.exception;
>
> and then refer to:
>
> std.bad_exception
>
> or:
>
> import exception = core.stdcpp.exception;
>
> exception.bad_exception;
>
> or whatever works best for one's project. Aliasing and import
> renaming (which are really just more aliasing) is very capable,
> and was designed for just these sorts of issues.
I think we're talking past each other. I know how to alias in D,
and how to use `using` in C++. What I'm saying is that, with the
file we have now (core.stdcpp.exception):
extern(C++, std) {
class exception { /* ... */ }
}
Currently the fully qualified name of `exception` is
`core.stdcpp.exception.std.exception`. I'm arguing that this is a
mistake, and the the FQN should instead be
`core.stdcpp.exception.exception`.
Yes, namespaces introduce scope in C++. Yes, lookup rules in C++
are crazy. The main points I'm (and, I think, Manu) arguing are:
1. We already have D packages, modules, and overload rules. We
don't need to import any from C++
2. That namespaces introduce a scope in C++ does not mean that
`extern(C++, ns)` should introduce one in D
i.e. Keep everything about D as-is, _except_ for no scoping for
`extern(C++, ns)`.
More information about the Digitalmars-d
mailing list