Reputation: 8797
Suppose I have two struct
s:
struct X {};
struct Y { X x; }
I have functions:
void f(X&);
void f(X&&);
How do I write a function g()
that takes Y&
or Y&&
but perfect forwarding X&
or X&&
to f()
, respectively:
template <typename T>
void g(T&& t) {
if (is_lvalue_reference<T>::value) {
f(t.x);
} else {
f(move(t.x));
}
}
The above code illustrate my intention but is not very scalable as the number of parameters grows. Is there a way make it work for perfect forwarding and make it scalable?
Upvotes: 18
Views: 1782
Reputation: 506847
template <typename T>
void g(T&& t) {
f(std::forward<T>(t).x);
}
Upvotes: 26
Reputation: 53017
I think this will work, although I'm not sure:
template<class T, class M>
struct mforward {
using type = M&&;
};
template<class T, class M>
struct mforward<T&, M> {
using type = M&;
};
template <typename T>
void g(T&& t) {
f(std::forward<typename mforward<T, decltype(t.x)>::type>(t.x));
}
Upvotes: 3