Consider the following code:
template<typename T> void foo(T&& some_struct)
{
bar(std::forward</* what to put here? */>(some_struct.member));
}
In the case of forwarding the whole struct I would do std::forward<T>(some_struct)
. But how do I get the correct type when forwarding a member?
One idea I had was using decltype(some_struct.member)
, but that seems to always yield the base type of that member (as defined in the struct definition).
Member access is value category preserving. If the object expression is an lvalue, so is the member access, otherwise it is an xvalue (like the result of std::move
). So do member access on the result of forwarding the object.
std::forward<T>(some_struct).member
As explained by @StoryTeller, if you forward the struct then the member value catogory is preserved (I think this is important to keep in mind). But how do I get the correct type when forwarding a member? you could do something like this:
template <typename T>
void foo(T&& some_struct) {
bar(std::forward<decltype(std::declval<T>().member)>(some_struct.member));
}
In this code the actual object that's being forwarded is the member and not the object. As forwarding is a just conditional move, you might want to look at this two articles: enter link description here enter link description here
Member access does the right thing here: you just need std::forward<T>(some_struct).member
.
Tested with:
template <class... >
struct check;
struct Foo {
int i;
};
template <class T>
void bar(T &&f) {
// fatal error: implicit instantiation of undefined template 'check<int &&>'
check<decltype((std::forward<T>(f).i))>{};
}
int main() {
bar(Foo{42});
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With