Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> C++

Template is_rvalue_reference trong C++ STL

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 Tis_lvalue_referenceis_rvalue_referenceis_reference
intfalsefalsefalse
int&truefalsetrue
int&&falsetruetrue
const int&truefalsetrue
const int&&falsetruetrue

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.