C++类型推导

C++类型推导,第1张

C++类型推导 typeof

gcc only

C++11标准前 类似decltype功能的运算符

typeid

获取目标 *** 作数类型的运算符 返回的是左值 只会涉及基本类型 不包含CV限定符和引用

auto
  1. 对于变量 从它的初始化器推导出它的类型(Since C++11)
  2. 对于函数 从它的return语句推导出类型(Since C++14)
  3. 对于非类型模板形参 指定要从实参推导出它的类型(Since C++20)

可配合cv限定符和&/*(引用/指针)这样的修饰符一起使用

decltype

3条推导规则

  1. 如果实参是没有括号的标识表达式或类成员访问表达式 那么 decltype 产生以该表达式命名的实体的类型
    1. 如果没有这种实体或该实参指名了一组重载函数 那么程序非良构(即错误的)
    2. 如果实参是指名某个结构化绑定的没有括号的标识表达式 那么 decltype 产生其被引用类型(Since C++17)
    3. 如果实参是指名某个非类型模板形参的没有括号的标识表达式 那么 decltype 生成该模板形参的类型(当该模板形参以占位符类型声明时,类型会先进行任何所需的类型推导)(Since C++20)
  2. 如果实参是其他类型为 T(可以是不完整类型) 的任何表达式
    1. 如果 表达式 的值类别是亡值 将会 decltype->T&&
    2. 如果 表达式 的值类别是左值 将会 decltype->T&
    3. 如果 表达式 的值类别是纯右值 将会 decltype->T
    4. 如果 表达式 是返回类类型纯右值的函数调用 或是右 *** 作数为这种函数调用的逗号表达式 那么不会对该纯右值引入临时量 (Before C++17)
    5. 如果 表达式 是~~除了(可带括号的)立即调用以外的 (Since C++20)~~纯右值,那么不会从该纯右值实质化临时对象:即这种纯右值没有结果对象。(Since C++17)
  3. 如果对象的名字带有括号 那么它会被当做通常的左值表达式 从而decltype(x)decltype((x)) 通常是不同的类型

对于第一条规则

#include
#include
int main(){
  int i = 0;
  int* j=&i;
  int n[10];
  decltype(i=0); // int& // 但不会赋值(Clang)
  // rule 1
  static_assert(std::is_same_v<decltype(i = 0), int&>);
  static_assert(std::is_same_v<decltype(n[5]), int&>);
  static_assert(std::is_same_v<decltype(*j), int&>);
  static_assert(std::is_same_v<decltype(static_cast<int&&>(i)), int&&>);
  static_assert(std::is_same_v<decltype(i++), int>);
  static_assert(std::is_same_v<decltype(++i), int&>);

  // rule 2
  static_assert(std::is_same_v<decltype(std::move(i)), int&&>); // xvalue
  static_assert(std::is_same_v<decltype(0, i), int&>); // comma/lvalue
  static_assert(std::is_same_v<decltype(i, 0), int>); // rvalue
  static_assert(std::is_same_v<decltype("hello world"), const char(&)[12]>); // lvalue

  // rule 3
  static_assert(std::is_same_v<decltype((i)), int&>);
}

:::tip cv限定符
通常情况下 decltype 会推导出cv限定符

但当表达式是成员变量时 父对象的限定符会被忽略

struct A {
  double x;
};
const A* a = new A();
static_assert(std::is_same_v<decltype(a->x),double>);
static_assert(std::is_same_v<decltype((a->x)),const double&>);

但多加一层括号会改变结果
:::

decltype(auto)

Since C++14

  1. 只能独立使用(不能搭配cv限定 指针/引用)
  2. 使auto推导使用decltype方式

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1325901.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-12
下一篇 2022-06-12

发表评论

登录后才能评论

评论列表(0条)

保存