user17597436
user17597436

Reputation:

Lvalue-to-rvalue conversion C++

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 ?

Edit : enter image description here

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

Upvotes: 1

Views: 384

Answers (1)

Caleth
Caleth

Reputation: 62719

in Example 1 Lvalue-to-rvalue conversion is applied to the two operands ( x and 0 )

No. The expression x is an lvalue, so it is converted. The expression 0 is already an rvalue, so it is not.

Lvalue-to-rvalue conversion is never applied to class type .

No. There is a sentence starting "Otherwise" after the non-class type case, there is a different rule for class types.

Upvotes: 2

Related Questions