std::is_rvalue_reference (header <type_traits>) kiểm tra xem kiểu T có phải là rvalue reference (T&&) hay không.
Rvalue và Rvalue Reference
- Rvalue: Biểu thức tạm thời, không có tên, thường ở bên phải phép gán. VD: literal
42,x + y,std::move(x). - Rvalue reference: Kiểu
T&&, liên kết với rvalue. Dùng cho move semantics và perfect forwarding.
Cú pháp
template <class T> struct is_rvalue_reference;
Ví dụ kiểm tra
#include <iostream>
#include <type_traits>
using namespace std;
int main() {
cout << boolalpha;
cout << "Kiểm tra is_rvalue_reference:\n";
// Kiểu cơ bản
cout << "int: " << is_rvalue_reference<int>::value << '\n'; // false
cout << "int&: " << is_rvalue_reference<int&>::value << '\n'; // false
cout << "int&&: " << is_rvalue_reference<int&&>::value << '\n'; // true
cout << "char: " << is_rvalue_reference<char>::value << '\n'; // false
cout << "char&: " << is_rvalue_reference<char&>::value << '\n'; // false
cout << "char&&: " << is_rvalue_reference<char&&>::value << '\n'; // true
cout << "float: " << is_rvalue_reference<float>::value << '\n'; // false
cout << "float&: " << is_rvalue_reference<float&>::value << '\n'; // false
cout << "float&&: " << is_rvalue_reference<float&&>::value << '\n'; // true
cout << "double: " << is_rvalue_reference<double>::value << '\n'; // false
cout << "double&: " << is_rvalue_reference<double&>::value << '\n'; // false
cout << "double&&: " << is_rvalue_reference<double&&>::value << '\n'; // true
// Class
class TP { };
cout << "TP: " << is_rvalue_reference<TP>::value << '\n'; // false
cout << "TP&: " << is_rvalue_reference<TP&>::value << '\n'; // false
cout << "TP&&: " << is_rvalue_reference<TP&&>::value << '\n'; // true
// Con trỏ
cout << "int*: " << is_rvalue_reference<int*>::value << '\n'; // false
cout << "int*&&: " << is_rvalue_reference<int*&&>::value << '\n'; // true
return 0;
}
Đầu ra
Kiểm tra is_rvalue_reference: int: false int&: false int&&: true char: false char&: false char&&: true float: false float&: false float&&: true double: false double&: false double&&: true TP: false TP&: false TP&&: true int*: false int*&&: true
So sánh với is_lvalue_reference
| Kiểu T | is_lvalue_reference | is_rvalue_reference | is_reference |
|---|---|---|---|
int | false | false | false |
int& | true | false | true |
int&& | false | true | true |
const int& | true | false | true |
const int&& | false | true | true |
Mối quan hệ
is_reference ≡ is_lvalue_reference || is_rvalue_reference
Ứng dụng
- Perfect forwarding: Phân biệt lvalue/rvalue để forward đúng.
- SFINAE: Overload cho rvalue reference (move) vs lvalue reference (copy).
- Type traits composition: Xây dựng trait phức tạp hơn.
Lưu ý quan trọng
Universal reference (forwarding reference) trong template template<class T> void f(T&& param) có thể là lvalue reference HOẶC rvalue reference tùy đối số truyền vào. is_rvalue_reference<T> kiểm tra kiểu T sau deduction, không phải kiểu của param.