C++ 通用引用

通用引用(universal reference) 是用来特指一种引用的类型. 构成通用引用有两个条件:

  • 必须满足T&&这种形式
  • 类型T必须是通过推断得到的

下面看一个例子:

template <typename T>
class A {
    void func(T&& t) {}
}

上面的例子中func 函数的T&&不是 通用引用. 因为在类定义变量时, 类型T就已经确定了,并不需要进行推断. 如: A<int> a;

哪些情况下是通用引用呢:

  • 函数模板参数:
  #include <iostream>
  #include <type_traits>

  template <typename T> void print_reference_type(T &&i) {
      if (std::is_lvalue_reference<decltype(i)>::value) {
          std::cout << "lvalue: " << i << std::endl;
      } else if (std::is_rvalue_reference<decltype(i)>::value) {
          std::cout << "rvalue: " << i << std::endl;
      } else {
          std::cout << "unknown value: " << i << std::endl;
      }
  }

  int main(void) {
      int i = 0;
      print_reference_type(i);  // lvalue: 0
      print_reference_type(1); // rvalue: 1
  }
  • auto声明:
  #include <iostream>
  #include <type_traits>

  void print_reference_type(auto &&i) {
      if (std::is_lvalue_reference<decltype(i)>::value) {
          std::cout << "lvalue: " << i << std::endl;
      } else if (std::is_rvalue_reference<decltype(i)>::value) {
          std::cout << "rvalue: " << i << std::endl;
      } else {
          std::cout << "unknown value: " << i << std::endl;
      }
  }

  int main(void) {
      int i = 0;
      print_reference_type(i);  // lvalue: 0
      print_reference_type(1); // rvalue: 1
  }

那通用引用与其他引用有什么区别呢? 最重要的区别是引用类型合成(Reference Collapsing Rules). 规则很简单:

  • T& & => T&
  • T&& & => T&
  • T& && => T&
  • T&& && => T&&

简单来说, 就是传进来的如果是左值引用那就是左值引用, 如果是右值引用那就是右值引用. 如果觉得有帮助,可以扫描右边的微信打赏码支持一下.

Leave a Reply

Your email address will not be published. Required fields are marked *