On 29 November 2015 at 14:57, Walter Bright via Digitalmars-d <digitalmars-d@puremagic.com> wrote: > > 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.
Then the feature fails. You can't put the entire STL in one file. C++ doesn't namespace per file, it generally namespaces per project... so this is the common case; every module define symbols in the same C++ namespace. >> 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. I understand, and that's fine, but it's not particularly useful unless I can make the namespace invisible and alias the namespaced symbols into D's module (user-accessible) scope. Otherwise importing 2 modules leads to conflicting namespace and symbol resolution is all messed up. >> 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. Maybe a special case for C++ namespaces? Or some other solution that produces the same result. It's a weird sort of permission this one, it's not that the symbols are 'private'; I intend the user to use them, I just want the C++ hierarchy excluded from the symbol table and only accessibly by controlled/explicit alias. >> 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. I don't think I'm doing that at all, I'm just trying to make some C++ code linkable to D, and it doesn't work at all. I think you misunderstood my entire post, I don't want C++ semantics at all, I just want to mangle like C++ for linkage, but the implementation doesn't let me do that. If anything, I'm trying to make C++ extern's behave like D semantics, but namespaces aren't a normal part of D, and don't really have idioms for dealing with this. C++ tends to namespace everything with the same namespace, and that means either I implement the entire C++ library in a single module (no way), or I face this mess. The feature just doesn't work beyond a single file linkage experiment, or I completely missed how I'm supposed to use it.