Pimpl
mrs_lib::Pimpl
-
template<typename Interface, typename StorageType = std::unique_ptr<Interface>>
class Pimpl Owning pointer wrapper with move only value semantics. Usefull for implementing the pointer to implementation (PIMPL) pattern.
Contains the specified value using the StorageType. Compared to std::*_ptr, this class uses deep const semantics and is not nullable (with the exception of the moved from state in which it should not be used).
When implementing the PIMPL pattern for your own classes, the default pointer type should be correct.
This class can also be used to wrap non nullable ros interfaces (eg.
rclcpp::Publisher), which are provided as std::shared_ptr. In those cases you can set StorageType to std::shared_ptr (eg. for the publisher:mrs_lib::Pimpl<rclcpp::Publisher, std::shared_ptr<rclcpp::Publisher>>). The class will keep the same semantics, but will use different storage.- Template Parameters:
Interface – The interface / class type that the Pimpl will hold.
StorageType – The type of value used to store for the implementation (defaults to
std::unique_ptr<Interface>).
Public Functions
-
explicit Pimpl(std::nullptr_t) = delete
Deleted constructor to prevent construction from nullptr.
-
inline explicit Pimpl(StorageType impl)
Construct Pimpl from a pointer to the object.
- Parameters:
impl – The pointer to the implementation object.
- Throws:
std::logic_error – if impl is
nullptr.
-
template<typename T, typename ...Args>
inline explicit Pimpl(std::in_place_type_t<T>, Args&&... args) Construct the wrapped object in place.
- Template Parameters:
T – The concrete type of the object to construct.
Args – Types of arguments passed to the inner object’s constructor.
- Parameters:
- – Tag type to distinguish between overloads and select the concrete type.
args – Arguments to construct the inner object with.
-
~Pimpl() = default
Default destructor.
-
inline Interface &operator*() noexcept
Dereference operator for non-const access.
- Returns:
Reference to the underlying implementation object.
-
inline const Interface &operator*() const noexcept
Dereference operator for const access.
- Returns:
Reference to the underlying implementation object.
-
inline Interface *operator->() noexcept
Arrow operator for non-const access.
- Returns:
Pointer to the underlying implementation object.
-
inline const Interface *operator->() const noexcept
Arrow operator for const access.
- Returns:
Pointer to the underlying implementation object.
-
inline bool valueless_after_move() const noexcept
Checks if the object is in moved from state.
Can be used on moved from object.
Note
This function should not be needed in most cases. You should not keep moved from objects alive for long periods of time.
Example
1class MyClass
2{
3 class Impl;
4
5public:
6 MyClass() : impl_(std::in_place_type_t<Impl>{}, 21)
7 {
8 }
9
10 int calculate();
11
12private:
13 mrs_lib::Pimpl<Impl> impl_;
14};
15
16class MyClass::Impl
17{
18public:
19 Impl(int val) : val_(val)
20 {
21 }
22
23 int calculate()
24 {
25 return val_ * 2;
26 }
27
28private:
29 int val_;
30};
31
32int MyClass::calculate()
33{
34 return impl_->calculate();
35}