Skip to content

Add utilities for working with `std::reference_wrapper`

Carsten Gräser requested to merge feature/referencehelper into master

This adds three utilities (stolen from staging/dune-functions!315 (merged)) and a corresponding test for working with std::reference_wrapper:

  • IsReferenceWrapper_v<T> allows to check if T is an instantiation of std::reference_wrapper
  • The function resolveRef(t) either returns t.get() or t depending on whether t is a std::reference_wrapper or a plain l-value reference.
  • ResolveRef_t<T> provides the resolved type for T.

These utilities allow to support storing data members of classes by value or reference transparently suing the following pattern. The class always stores values, but supports passing std::ref(...) to opt-in store-by-reference. Handling the latter can be done without boilerplate code using the provided utilities:

template<class StoredT>
struct SomeWrapper {

  using T = ResolveRef_t<StoredT>;

  SomeWrapper(const StoredT& t) : t_(t) {}

  void callFoo() const {
    resolveRef(t_).foo();
  }

  StoredT t_;
};

[...]

// Store t by value
auto w1 = SomeWrapper(t);
w1.callFoo();

// Store t by reference
auto w2 = SomeWrapper(std::cref(t));
w2.callFoo();

Merge request reports