Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

If I accept a parameter via universal reference, is exactly one of is_rvalue_reference and is_lvalue_reference true?

Is it ever possible for this code to print "neither"?

using namespace std;
template<typename T>
void foo(T&& t) {
    if constexpr (is_lvalue_reference_v<T>) {
        cout << "lv" << endl;
    } else if constexpr (is_rvalue_reference_v<T>) {
        cout << "rv" << endl;
    } else {
        cout <<"neither" << endl;
    }
}
like image 457
Drew Avatar asked Nov 27 '25 18:11

Drew


2 Answers

Is it ever possible for this code to print "neither"?

Yes, "neither" will be printed any time an rvalue is passed to foo and no explicit template parameter is given:

foo(42);  // "neither" is printed because T is deduced as int

Or when a non-reference type is explicitly specified:

int i=0;
// "neither" is printed because T is explicitly specified as int:
foo<int>(std::move(i));

While T can be a non-reference type, the type of t will always be a reference type. There are three possibilities for the type of t:

  1. T is a value type (i.e. int): the type of t is int&&; rvalue-reference to int.
  2. T is an lvalue-reference (i.e. int&): the type of t is int& &&, which collapses to int&; lvalue-reference to int.
  3. T is an rvalue-reference (i.e. int&&): the type of t is int&& &&, which collapses to int&&; rvalue-reference to int.

This is the mechanism by which forwarding references work. If you pass an rvalue to foo, then T will be deduced to be a value type. If you pass an lvalue then T will be deduced to be an lvalue-reference type.

like image 173
Miles Budnek Avatar answered Nov 29 '25 06:11

Miles Budnek


Is it ever possible for this code to print "neither"?

Yes.

foo(5); // neither

If I accept a parameter via universal reference, is exactly one of is_rvalue_reference and is_lvalue_reference true?

The parameter t will either have rvalue reference type or lvalue reference type. The type T on the other hand will be different depending on deduction and reference collapsing rules. If instead you change is_lvalue/rvalue_reference<T> to is_lvalue/rvalue_reference<decltype(t)> then the else path can never be executed.

like image 28
David G Avatar answered Nov 29 '25 07:11

David G



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!