Тhe Pimpl base class (aliased as impl_ptr_type) is initialized with:
Book::Book(string const& title, string const& author) : impl_ptr_type(in_place, title, author) {}
In line with std::optional, std::variant and std::any the in_place argument is the disambiguation tag indicating that the underlying impl_ptr<Book>::implementation is constructed in-place with the remaining arguments. Consequently, a Book constructor with no matching impl_ptr<Book>::implementation constructor will fail to compile. Same goes for the default constructor:
Book::Book() : impl_ptr_type(in_place) {}
will try calling the default implementation() constructor and will fail to compile if there is no such.
To avoid potential ambiguity impl_ptr_type does not have the default constructor. To create a proxy with no implementation (if such is needed) initialize impl_ptr_type explicitly as:
Book::Book() : impl_ptr_type(nullptr) { // A Book proxy object is created with no implementation. }
or use boost::impl_ptr<Book>::null():
Book::Book() : impl_ptr_type(boost::impl_ptr<Book>null()) { // A Book proxy object is created with no implementation. } void Book::do_something() { if (!*this) // If no implementation, create one. { // Implementation is created later. impl_ptr_type::emplace(args); } ... }
In the example the underlying impl_ptr_type and, consequently, Book are created "invalid" (like nullptr or an empty std::shared_ptr()). Later an impl_ptr_type<Book>::implementation instance is explicitly created using impl_ptr_type::emplace().
That nullptr-like concept is generalized via impl_ptr<Book>::null(). That is useful for lazy-instantiation optimization (as in the example above) or to support dynamic polymorphism (as discussed later) or to indicate a no-book condition:
Book find_book() { ... return boost::impl_ptr<Book>::null(); // found nothing } ... if (Book book = find_book()) do something useful; else report book-not-found;
It is probably worth mentioning that impl_ptr<Book>::null() is not part of Book public interface. It is up to the Book implementer to decide if such
Book::Book() : impl_ptr_type(nullptr) {}
"invalid" Book needs to be part of the public interface, if impl_ptr<Book>::null() is used internally, or if that functionality is used at all.