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.
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>>>
.
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.
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