Skip to content

Instantly share code, notes, and snippets.

@andijcr
Last active December 15, 2022 13:07
Show Gist options
  • Save andijcr/8c5c3d8f35cede3d94a556962a3f51a0 to your computer and use it in GitHub Desktop.
Save andijcr/8c5c3d8f35cede3d94a556962a3f51a0 to your computer and use it in GitHub Desktop.
const ref parameter that rejects termporaries
// problem: we want to pass a const reference, but we want to prevent temporary
// to bind to it
// a type and a subtype to run the tests
struct type {
int v;
};
struct subtype : public type {
int vv;
};
// option 1: just delete it, does not scale well with the number of parameters
void foo_explicit(type&&) = delete;
void foo_explicit(type const& t) { auto v = t.v; };
// option 2: use a ref_wrap. requires functional, ugly use
#include <functional>
#include <type_traits>
void foo_refwrap(std::reference_wrapper<const type> t) { auto v = t.get().v; }
// option 3: write a dumbo ref_wrap (const). simpler than including functional?
template <typename T>
struct my_cref_wrap {
const T& internal;
constexpr my_cref_wrap(const T& v) noexcept : internal{v} {}
my_cref_wrap(T&&) = delete;
};
void foo_mycrefwrap(my_cref_wrap<type> t) { auto v = t.internal.v; }
// option 4: a concept. it's like a wrapper, simpler(?) but it is template
template <typename T, typename U>
concept not_temp = std::derived_from<std::decay_t<T>, std::decay_t<U>> &&
(!std::is_rvalue_reference_v<U>);
void foo_concept(not_temp<type> auto const& t) { auto v = t.v; }
int main() {
auto a = subtype{};
auto const ca = subtype{};
auto& ra = a;
auto& cra = ca;
foo_explicit(a);
foo_explicit(ca);
foo_explicit(ra);
foo_explicit(cra);
// foo_explicit(subtype{}); // error
foo_refwrap(a);
foo_refwrap(a);
foo_refwrap(ra);
foo_refwrap(cra);
// foo_refwrap(subtype{}); // error
foo_mycrefwrap(a);
foo_mycrefwrap(a);
foo_mycrefwrap(ra);
foo_mycrefwrap(cra);
// foo_mycrefwrap(subtype{}); // error
foo_concept(a);
foo_concept(a);
foo_concept(ra);
foo_concept(cra);
// foo_concept(subtype{}); // error
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment