0

I have a question about creating a lock adapter, and more generally the adapter pattern with style of implementation below. The implementation below based on the answer in Proper C++ way of implementing a lock_guard for custom library. The implementation relies on public inheritance of the new interface (class in this case) and private inheritance of the legacy interface. However there doesn't seem to be a clean way of passing the lock_adapter to unique_lock, i.e. since adapted_unique_lock is not a lock_adapter as the author might have intended, i.e. this does not compile.

template<class T>
struct lock_adapter {
  T* t = nullptr;
  void lock() { t->Lock(); }
  void unlock() { t->Unlock(); }
  lock_adapter( T& tin ):t(std::addressof(tin)) {}
  // default some stuff if you like
};

template<class T>
struct adapted_unique_lock:
  private lock_adapter<T>,
  std::unique_lock< lock_adapter<T> >
{
  template<class...Args>
  adapted_unique_lock(T& t, Args&&...):
    lock_adapter<T>(t),
    std::unique_lock< lock_adapter<T> >( *this, std::forward<Args>(args)... )
  {}
  adapted_unique_lock(adapted_unique_lock&&)=delete; // sadly
  friend void swap( adapted_unique_lock&, adapted_unique_lock& ) = delete; // ditto
};

For this specific instance, doing something simple instead such as below works with direct adaptation of unique_lock.

struct L1
{
    void Lock(){}
    void Unlock() {}
};


 void test()
 {
     L1 l;
     lock_adapter<L1> l_adapt(l);
     unique_lock<lock_adapter<L1>> u(l_adapt)
 }

My question is if there is a way to get the original implementation that uses a mix of private and public inheritance working which would need for the private base to be passed into the public base class?

user3882729
  • 1,339
  • 8
  • 11
  • `std::unique_lock` is not meant to be derived from. I don't understand what `adapted_unique_lock` is supposed to achieve. That said, you can make it compile with a cast: `static_cast&>(*this)` in place of `*this`. [Demo](https://rextester.com/JRXJNJ61382) – Igor Tandetnik May 02 '20 at 20:28
  • Thanks Igor. Because lock_adapter is inherited privately, IOW does not follow the is-a relationship of public inheritance, is constructing unique_lock> with **this* still appropriate? – user3882729 May 02 '20 at 20:36
  • `lock_adapter` here is essentially a data member. The only reason to make it a private base class instead is to ensure that it's constructed first, before `unique_lock`. `adapted_unique_lock` does not rely on is-a relationship or anything like that - just on having a sub-object of type `lock_adapter`. The fact that this sub-object is accessed via a quirky syntax like `static_cast&>(*this)` is not really relevant. – Igor Tandetnik May 02 '20 at 20:42

0 Answers0