I read about Lvalue-to-rvalue conversion and Comparison operators
This quote from Comparison operators :
after the application of the lvalue-to-rvalue, array-to-pointer and function-to-pointer standard conversions. The comparison is deprecated if both operands have array type prior to the application of these conversions. (since C++20)
This quote from Lvalue-to-rvalue conversion :
An lvalue (until C++11)A glvalue (since C++11) of any non-function, non-array type T can be implicitly converted to an rvalue (until C++11)a prvalue (since C++11):
If T is not a class type, the type of the rvalue (until C++11)prvalue (since C++11) is the cv-unqualified version of T. Otherwise, the type of the rvalue (until C++11)prvalue (since C++11) is T. If an lvalue-to-rvalue conversion from an incomplete type is required by a program, that program is ill-formed.
I just want to make sure that I understand how this conversion works right ( My Understand ) :
Example 1 :
#include <iostream>
using namespace std;
int main() {
int x=9;
if(x == 0){
cout<<"Okay"<<endl;
}
return 0;
}
Example 2 :
#include <iostream>
using namespace std;
int main() {
int x=9;
if(0 == x){
cout<<"Okay"<<endl;
}
return 0;
}
I concluded two points :
The point number 1 : in Example 1
Lvalue-to-rvalue conversion is applied to the two operands ( x and 0 )
of the operator ==
before the The comparison
and that is why the Example 2
is also compiled and run .
The point number 2 : Lvalue-to-rvalue conversion is never applied to class type . ( is that the exact meaning of this section ( because the english is not my native language so I want to make sure that I understand this section totally right ) ? : )
If T is not a class type, the type of the rvalue (until C++11)prvalue (since C++11) is the cv-unqualified version of T. Otherwise, the type of the rvalue (until C++11)prvalue (since C++11) is T. If an lvalue-to-rvalue conversion from an incomplete type is required by a program, that program is ill-formed.
So at the end is my conclusion ( the two points ) totally right ?
here the Inside class definition of operators and the Outside class definition
for example for equal to Operator ( == ) the Inside class definition is ( for class T )
bool T::operator==(const T2& b) const;
and the Outside class definition is bool operator==(const T& a, const T2& b);
So I have four questions for you @Caleth you in your last comment ( under your answer ) " bool operator==(int &, Foo&)
takes lvalues, whereas bool operator(int, Bar)
takes rvalues "
question number 1 - what I understand from your comment is Foo
is a class and Bar
is also a class is that right ?
you said in another comment " for the built-in operators, i.e. both operands are of scalar type, then lvalue-to-rvalue conversion is done because all built-in operators are by-value. For user defined operators, it is or isn't done depending on the declared type of the parameter "
question number 2 - " the built-in operators, i.e. both operands are of scalar type, then lvalue-to-rvalue conversion is done because all built-in operators are by-value. " I don not understand you said " because all built-in operators are by-value. " when we take a look on the table ( the photo ) we can see that the Outside class definition is bool operator==(const T& a, const T2& b);
Is the Outside class definition the definition of built-in operators ?
question number 3 - if the answer of the question number 2 is YES then why is the lvalue-to-rvalue conversion done when we use built-in operators ( if the parameter in the definition of the built-in operators is not by - value ) and if the answer of the question number 2 is NO then What is the difference between Outside class definition and the definition of built-in operators ?
you said " For user defined operators, it is or isn't done depending on the declared type of the parameter " and you explain this by said " bool operator==(int &, Foo&)
takes lvalues, whereas bool operator(int, Bar)
takes rvalues " If we apply your words
#include <iostream>
using namespace std;
class test {
public:
test() {
cout << "test()" << endl;
}
test(test&& p) {
cout << "test( test&& p )" << endl;
}
test(const test& p) {
cout << "test( const test& p )" << endl;
}
test& operator==(test p) {
return p;
}
};
int main() {
test p;
test o;
p == o;
return 0;
}
the output of this code is :
test() ------- for test p
test() ------- for test o
test( const test& p ) -------- for operator ==
so here the parameter of the overloaded operator ==
is test p
( is by - value ) and the lvalue-to-rvalue conversion does not applied
question number 4 - does not that make the lvalue-to-rvalue conversion does not applied when you use a class type ( any class type ) with an overloaded operator ( any overloaded operator ) ( even if the parameter of the overloaded operator is by - value or not ) ( there is no case that the lvalue-to-rvalue conversion is applied when you use a class type ( any class type ) with an overloaded operator ( any overloaded operator ) ) ?
you said "There are user-defined operators that require lvalue-to-rvalue conversions, e.g. bool operator==(int, Bar), and ones that don't, e.g. bool operator==(int &, Foo&)."
question number 5 - you said " bool operator==(int, Bar)
requires lvalue-to-rvalue conversions "
here bool operator==(int, Bar)
The lvalue-to-rvalue conversion happens with the parameter int
and The lvalue-to-rvalue conversion does not happen with the parameter Bar
, right ?
sorry for bothering you @Caleth