Reputation: 1590
I have a struct F
with a function foo
that has different implementation whether F
is a temporary or not
struct F{
void foo() & { std::cout << "F::foo() &" << std::endl; }
void foo() && { std::cout << "F::foo() &&" << std::endl; }
};
Another struct A
has a copy of F
and in its function bar
calls F::foo
. I want to use the correct version of F::foo()
. Therefore the implementation is:
struct A{
void bar() & {
f.foo();
}
void bar() && {
std::move(f).foo();
}
F f;
};
I'm wondering if I really have to provide two implementations of A::bar()
. Isn't there a smart way to use std::forward
to automatically decide which F::foo()
should be used?
An attempt:
struct B{
void bar() {
std::forward<F>(f).foo();
}
F f;
};
However, this does not work. It calls F::foo() &&
every time.
Upvotes: 6
Views: 329
Reputation: 38267
No, there is no shortcut available at this point and you will need to stick to the verbose version. But have a look at p0847, "Deducing this
". Not sure what the status of this proposal is, however. From the abstract:
We propose a new mechanism for specifying or deducing the value category of an instance of a class. In other words, a way to tell from within a member function whether the object it’s invoked on is an lvalue or an rvalue, and whether it is const or volatile.
Upvotes: 5
Reputation: 39101
You can use a non-member function template:
struct B{
template<typename TB>
friend void bar(TB&& self) {
std::forward<TB>(self).f.foo();
}
F f;
};
Depending on other function parameters, you might want to restrict the type of TB
such that is_base_of_v<B, remove_const_t<remove_reference_t<TB>>>
.
Upvotes: 5