2

e.g. I have a function that can handle const T & and T && values:

template <typename T>
/* ... */ foo(const T &) {
std::cout << "const T & as arg" << std::endl;
}

template <typename T>
/* ... */ foo(T &&) {
std::cout << "T && as arg" << std::endl;
}

Is there a way that I can write a single function, that handles both types automatically? As in:

template <typename T>
/* ... */ bar(T t) {
    foo(t);
}

So that:

T a;
bar(a); // Handles as const T &
T b;
bar(std::move(b)); // Handles as T &&

Thank you!

Chris Drew
  • 14,926
  • 3
  • 34
  • 54
Philipp H.
  • 1,513
  • 3
  • 17
  • 31

1 Answers1

8

You can use reference collapsing and std::forward to forward the argument to the foo function:

template <typename T>
/* ... */ bar(T&& t) {
    foo(std::forward<T>(t));
}

Please notice that your foo function will accept rvalues, constant lvalues and non-const lvalues. As an example, given:

const int x = 456;
int y = 123;

then:

foo(123);   // foo(T&&)
foo(x);     // foo(const T&)
foo(y);     // foo(T&&)

Live demo

Shoe
  • 74,840
  • 36
  • 166
  • 272