I'm confused by the following code:
struct test {
void f() & {
std::cout << "&" << std::endl;
}
void f() const& {
std::cout << "const&" << std::endl;
}
void f() && {
std::cout << "&&" << std::endl;
}
void f() const&& {
std::cout << "const&&" << std::endl;
}
void g() & {
std::cout << "& -> ";
f();
}
void g() const& {
std::cout << "const& -> " ;
f();
}
void g() && {
std::cout << "&& -> ";
f();
}
void g() const&& {
std::cout << "const&& -> ";
f();
}
test() {} //allow default const construction
};
int main(int, char**) {
test value;
const test constant;
value.g();
constant.g();
std::move(value).g();
std::move(constant).g();
}
When I compile with clang 3.5 I get this output:
& -> &
const& -> const&
&& -> &
const&& -> const&
Why is the r-value qualifier being dropped here? And is there any way to call f
from g
with the right qualifier?
A function is defined as a relation between a set of inputs having one output each. In simple words, a function is a relationship between inputs where each input is related to exactly one output.
function, in mathematics, an expression, rule, or law that defines a relationship between one variable (the independent variable) and another variable (the dependent variable).
A function is a kind of rule that, for one input, it gives you one output. An example of this would be y=x2. If you put in anything for x, you get one output for y. We would say that y is a function of x since x is the input value.
The types of functions can be broadly classified into four types. Based on Element: One to one Function, many to one function, onto function, one to one and onto function, into function.
The call f()
is interpreted as (*this).f()
. The result of dereferencing a pointer is always an lvalue, so *this
is an lvalue and the lvalue-qualified function is called.
This behaviour even makes sense, at least to me. Most of the time the object referred to by an rvalue expression will either be destroyed at the end of the full-expression (a temporary) or at the end of the current scope (an automatic local variable that we choose to std::move
). But when you're inside a member function, neither of those is true, so the object should not treat itself as an rvalue, so to speak. This is also why it makes sense for the name of an rvalue reference function parameter to be an lvalue within the function.
If you want the rvalue-qualified f
to be called, you can do this:
std::move(*this).f();
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