On 11/28/2015 8:40 PM, Manu via Digitalmars-d wrote:
I'm having a lot of trouble with C++ namespaces.
The problem is, the namespace is not just attributed to the symbol in
D, but it's emulated as a named scope.

It is not "emulated" in D, it is an actual named scope in D.


The trouble mostly appears in this situation:

file1.d
   extern(C++, NS) struct X;

file2.d
   extern(C++, NS) struct Y;

file3.d
   import file1, file2;
   X x; // nope
   Y y; // nope
   NS.X x; // NS has multiple definitions...
   NS.Y y; // NS has multiple definitions...


And various other configurations similar to this where multiple files
declare symbols in the same C++ namespace, and then something tries to
import more than one of them.
Circular imports of this sort always cause problems.

D does not support C++ semantics. You cannot split namespaces into multiple files in D, nor can you add symbols to an existing namespace. For namespace NS, all the declarations in NS have to be in one file and between the { }, just like any other scope in D.


Additionally to that, I don't really want the C++ namespaces to be
visible to D; they should be for mangling purposes only.

We considered making them for mangling only, and rejected it as unworkable, because then two identical names in different namespaces could not be distinguished by the D symbol table system.


So I try code like this:
   private extern(C++, NS) struct Thing {}
   alias Thing = NS.Thing;

The idea being that NS will not be available externally, and they
should use Thing in module scope instead, but that doesnt work with
errors:
   Error: module blah class blah.NS.Thing is private

It seems aliasing a private thing into the public namespace does not
make it accessible via that alias?

Aliases do not change access permissions. They are just aliases.


The only way I've managed to make any of those work is with proxy
modules, which static import the C++ module, and then `alias Thing =
NS.Thing` into the proxy module's scope. This is horrid, and it
doubles my module count. I haven't found another pattern that's
reliably workable.

Ideas?

Stop trying to bash D into behaving like C++! It'll just make for horrid code (as you discovered) and make you miserable trying. D has an interface to C++; it does not have C++ semantics.

Reply via email to