decltype 注意事项

decltype能够获取一个表达式的类型. 而auto关键字是在赋值时获取变量的类型. decltype的一般用法: int a = 0; decltype(i) b = 0;.

decltype的用途:

  • 定义新类型:
  using nullptr_t = decltype(nullptr);
  • 获取匿名类型:
  struct {
      int m_a;
  } num = {.m_a = 0,};
  decltype(num) b;
  • 在泛型编程中与auto关键字结合, 实现类型自动推倒:
  #include <iostream>

  template <typename T, typename U>
  auto add(T x, U y)->decltype(x + y) {
      return x + y;
  }

  int main() {
      std::cout << add(1, 2.3) << std::endl; // 输出: 3.3
  }

decltype类型推导规则:

  • 不适用于重载函数.
  • 实体类型: 没有带括号的标记符表达式或类成员访问表达式.
  int i = 0;
  decltype(i) a = 0; // int

  int arr[2] = {0};
  decltype(arr) a = {0, 1}; // int(a)[2] = {0, 1};

  int *ptr = nullptr;
  decltype(ptr) a = nullptr; // int*

  struct num {int m_a;}n;
  decltype(n.m_a) a = 0; // int
  • 实体类型&&: 将亡值.
  int&& right_value_reference(){};
  decltype(right_value_reference()) a = 1; // int&&
  • 实体类型&: 左值.
  int i = 0;
  int *ptr = nullptr;
  decltype((i)) a = 0; // int&
  decltype (++i) a = 0; //int&  ++i返回i的左值
  decltype(arr[5]) a = 0;//int& []操作返回左值
  decltype(*ptr) a = 0;//int& *操作返回左值
  decltype("hello") a = "world"; // 符串字面常量为const左值
  • 实体类型: 上述情况都不是.
  int i = 0;
  decltype(1) a = 0; //const int
  decltype(Func(1)) a = true;//const bool
  decltype(i++) a = 0; //int i++返回右值

注意:

  • 非字符串字面量常量为右值, 使用最后一条规则.
  • 可通过std::is_lvalue_reference<decltype(++i)>::valuestd::is_rvalue_reference<decltype(++i)>::value 判断一个表达是左值还是右值. 例子:
  #include <iostream>
  #include <type_traits>

  int main() {
      int i = 0;
      std::cout << std::is_lvalue_reference<decltype(++i)>::value << std::endl; // 输出: 1
      std::cout << std::is_rvalue_reference<decltype(++i)>::value << std::endl; // 输出: 0
  }

如果觉得有帮助,可以扫描右边的微信打赏码支持一下.

Leave a Reply

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