Interesting. I did not know this. I would have thought Box<dyn Foo> would have achieved PIMPL. Is that not the case?
Interesting. I did not know this. I would have thought Box<dyn Foo> would have achieved PIMPL. Is that not the case?
Oops. Good catch. Fixed. :)
Sounds like this is a fixable problem though? That’s nice. I really appreciate the amount of attention Rust compile times is getting. (Especially because relative to C++ they aren’t actually that bad!)
The outer exposed API is called on `this` which then uses the internal `pimpl` pointer to actually call a function.
While it may speed up building, I have found it incredibly clunky to use in C++ and prefer to write my code without it, choosing instead for longer compilation times.
PIMPL is just a tool. There’s no argument here that it should be used in all or even many cases. The fact that C++ has this tool and Rust does not is interesting.
PIMPL indeed has overhead. Both when writing the code and when calling the code. If a program crosses the PIMPL boundary many times then the calling overhead can be meaningful.
However if the API is small and the program spends more time “inside” the PIMPL than crossing the boundary the runtime overhead is trivial.
A key benefit of PIMPL is that, in some cases, you can have a very lightweight header than clearly expresses an API without making users include a ton of dependencies they don’t actually need. I shall not express my opinion on C++ headers.
Historically I have not liked PIMPL. My current project benefits from it a great deal. Most projects probably would not. Like I said, it’s just one of many tools.
The consumer code then can use std::unique_ptr<iSomething> (the interface needs a virtual destructor for that) without including the implementation.
Just like PIMPL, this allows to replace implementation without breaking the ABI. Requires much less boilerplate compared to PIMPL. Compiler will automatically setup these function pointers without requiring to manually write the wrappers for public methods. As a nice bonus, compiler forces you to fully implement the interface or the std::make_unique line won’t compile.