1

Because of the confusing syntax of forwarding references and rvalue references, it's not clear to me how I would write a function that takes some type, T, by rvalue reference. That is, while

template <typename T> void foo(T x);

takes x by value and

template <typename T> void foo(T& x);

by reference, and

template <typename T> void foo(T* x);

by pointer, when we say

template <typename T> void foo(T&& x);

suddenly it's taking x by forwarding reference not by rvalue reference. What's the Right Way to say foo takes x by forwarding reference? Like this?

template <typename T>
void foo(T&& x) {
    static_assert(std::is_rvalue_reference_v<T&&>, "x must be an rvalue reference.");
Ben
  • 9,184
  • 1
  • 43
  • 56
  • 1
    The above is a good start, but this template will still participate in overload resolution which is usually undesirable. I'm too lazy to confirm this this, but you probably want an extra `typename=std::enable_if_t>` template parameter, instead. Or, even better, declare this whole thing as the return value, in place of an explicit `void`, if the extra template parameter looks too ugly in error messages. – Sam Varshavchik Feb 18 '22 at 13:35

1 Answers1

1
template<class T>
void f(T &&)
requires(!std::is_lvalue_reference_v<T>);
bipll
  • 11,747
  • 1
  • 18
  • 32
  • Do you mean `requires(!std::is_rvalue_reference_v)`? (Related to this question, I'm a little fuzzy on what `T` is in the case that the argument is `T&&`...) – Ben Feb 18 '22 at 13:36
  • 1
    Updated. It should be lvalue as rvalue references are harmless for matching against `T`. – bipll Feb 18 '22 at 22:35
  • @bpill is there any way it would wind up being a value rather than a reference type? Wouldn’t it be more direct to require it to be an rvalue reference? – Ben Feb 19 '22 at 14:55
  • 1
    See, if you call it with a rvalue (`f(T{});`) T is deduced to be a non-reference. You can also manually instantiate it with T being a rvalue reference: `f(U{});`; only lvalues are forbidden by the requirement. – bipll Feb 19 '22 at 17:58