November 29, 2015
On 29 November 2015 at 14:40, Manu <turkeyman@gmail.com> 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.
>
> 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.
>
> Additionally to that, I don't really want the C++ namespaces to be visible to D; they should be for mangling purposes only.
>
> 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?
>
> 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?

Oh yeah, I also tried renamed imports to get the namespaces symbols
into the module scope, like this:
  import blah : Thing = NS.Thing;

But that doesn't work.

The extern(C++) docs need to cover these cases and explain how the user is supposed to actually use the feature. I'm generally just stabbing in the dark :/
November 29, 2015
On 29 November 2015 at 14:54, Manu <turkeyman@gmail.com> wrote:
> On 29 November 2015 at 14:40, Manu <turkeyman@gmail.com> 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.
>>
>> 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.
>>
>> Additionally to that, I don't really want the C++ namespaces to be visible to D; they should be for mangling purposes only.
>>
>> 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?
>>
>> 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?
>
> Oh yeah, I also tried renamed imports to get the namespaces symbols
> into the module scope, like this:
>   import blah : Thing = NS.Thing;
>
> But that doesn't work.
>
> The extern(C++) docs need to cover these cases and explain how the user is supposed to actually use the feature. I'm generally just stabbing in the dark :/


Oh yeah, also, C++ namespaces seem to break forward referencing:

Error: identifier 'Thing' of 'NS.Thing' is not defined:
  alias Thing = NS.Thing;
  extern(C++, NS) struct Thing {}


Compiles fine:
  extern(C++, NS) struct Thing {}
  alias Thing = NS.Thing;