Thread overview
pImpl in D
Apr 04, 2017
Satoshi
Apr 04, 2017
Satoshi
Apr 04, 2017
Dejan Lekic
April 04, 2017
Hi,
do someone have any experience with pImpl and inheritance in D?

I tried something like:

// FooPrivate.d
class FooPrivate {
    int a;
}


// BarPrivate.d
import FooPivate;

class BarPrivate : FooPrivate {
    string b;
}


// Foo.d
import FooPrivate;

class Foo {
    protected FooPrivate m_private;

    this() { m_private = new FooPrivate; }
}


// Bar.d
import Foo;
import FooPrivate;
import BarPrivate;

class Bar : Foo {
    this() { m_private = new BarPrivate; }
}


And public interface
// Foo.di
class FooPrivate;
class Foo {
    private FooPrivate m_private;
}


Bar.d looks like it imported Foo with forward referenced FooPrivate and is unable to resolve it by importing FooPrivate.

Is this bug?
Do you know about any *less verbose* design pattern how I can hide implementaion details from .di files?

Thanks!
April 04, 2017
test/Foo.di(3,1): Error: class test.Foo.FooPrivate is forward referenced when looking for 'opAssign'

forward reference in Foo.di


test/Bar.d(14,25): Error: cannot implicitly convert expression (p) of type test.BarPrivate.BarPrivate to test.Foo.FooPrivate

I'm unable to cast from BarPrivate to FooPrivate because it can't recognize Bar : Foo; inheritance from Foo.di (FooPrivate.d and BarPrivate.d is ignored).


test/Foo.di(3,1): Error: class test.Foo.FooPrivate is forward referenced when looking for 'opCast'

same as first
April 04, 2017
On Tuesday, 4 April 2017 at 12:05:15 UTC, Satoshi wrote:
> Hi,
> do someone have any experience with pImpl and inheritance in D?

Some parts of Phobos use it. Example: https://github.com/dlang/phobos/blob/master/std/stdio.d
Have a look at the struct ByLine

It has something like:

    struct ByLine(Char, Terminator)
    {
    private:
        import std.typecons : RefCounted, RefCountedAutoInitialize;

        /* Ref-counting stops the source range's Impl
         * from getting out of sync after the range is copied, e.g.
         * when accessing range.front, then using std.range.take,
         * then accessing range.front again. */
        alias PImpl = RefCounted!(Impl, RefCountedAutoInitialize.no);
        PImpl impl;