c++ decltype

本文详细解释了C++中的decltype、typeid和typeof关键字,包括它们的作用、用法及区别,特别强调了decltype在编译时推导类型、typeid在运行时获取类型信息的应用场景。
摘要由CSDN通过智能技术生成

解释c++中的decltype,typeid和typeof关键字的作用和用法,以及它们之间的区别。

decltype:

这是C++11引入的一个关键字,它可以根据一个表达式的类型和值类别推导出一个类型。它常用于声明一些难以用标准语法表示的类型,例如lambda表达式的类型或者依赖于模板参数的类型。它也可以用于保留一个表达式的引用性和常量性,例如返回类型后置语法或者decltype(auto)的用法。

decltype的用法是在一个表达式前加上decltype关键字,例如decltype(x),它会返回x的类型。如果表达式是一个括号包围的左值,

例如decltype((x)),它会返回x的左值引用类型。decltype的规则有时候会比较复杂

typeid

这是C++98就有的一个运算符,它可以返回一个表达式或者一个类型的std::type_info对象的引用,该对象包含了类型的名称和其他信息。它常用于运行时的类型识别,例如判断一个对象的动态类型或者比较两个类型是否相同。typeid的用法是在一个表达式或者一个类型前加上typeid运算符,例如typeid(x)或者typeid(int),它会返回一个std::type_info对象的引用。如果表达式是一个多态类型的对象或者指针,typeid会返回该对象的动态类型,否则返回静态类型。typeid的结果可以用name()成员函数来获取类型的名称,但是这个名称是由编译器实现定义的,不一定是可读的或者一致的。您可以参考这个网页²来了解更多的细节和例子。

typeof

这是一个非标准的关键字,它在一些编译器中提供了类似于decltype的功能,即根据一个表达式的类型推导出一个类型。它的用法是在一个表达式前加上typeof关键字,例如typeof(x),它会返回x的类型。它和decltype的区别是,typeof不会区分左值和右值,也不会保留引用性和常量性。typeof也不是C++标准的一部分,所以不建议在可移植的代码中使用它。您可以参考这个网页³来了解更多的细节和例子。

以上是我为您解释的c++中的decltype,typeid和typeof关键字的作用和用法


(1) Is it possible to print a variable's type in standard C++?. https://stackoverflow.com/questions/81870/is-it-possible-to-print-a-variables-type-in-standard-c.
(2) decltype specifier - cppreference.com. https://en.cppreference.com/w/cpp/language/decltype.
(3) typeid operator - cppreference.com. https://en.cppreference.com/w/cpp/language/typeid.
(4) decltype and typeid returns different type - Stack Overflow. https://stackoverflow.com/questions/50424102/decltype-and-typeid-returns-different-type.

一些在代码中使用decltype,typeid和typeof关键字的场景和示例

但请注意,这些关键字并不是C语言标准的一部分,而是C++或者GNU C的特性,所以您可能需要使用相应的编译器和语言模式来编译和运行您的代码。

  • decltype:这个关键字可以用来在编译时推导出一个表达式的类型,它常用于以下几种场景:
    • 声明一个变量,但不知道它的确切类型,只知道它和另一个表达式的类型相同,例如:
      auto x = some_function(); // x的类型由some_function的返回值决定
      decltype(x) y = x; // y的类型和x的类型相同
      
    • 声明一个函数的返回类型,但不知道它的确切类型,只知道它和函数体中某个表达式的类型相同,例如:
      template<typename T, typename U>
      auto add(T t, U u) -> decltype(t + u) // 返回类型由t + u的类型决定
      {
          return t + u;
      }
      
    • 声明一个模板参数的类型,但不知道它的确切类型,只知道它和模板类或函数中某个表达式的类型相同,例如:
      template<typename Container>
      void print_elements(const Container& c)
      {
          for (auto it = c.begin(); it != c.end(); ++it)
          {
              decltype(*it) x = *it; // x的类型和容器中的元素类型相同
              std::cout << x << " ";
          }
          std::cout << std::endl;
      }
      
  • typeid:这个运算符可以用来在运行时获取一个表达式或者一个类型的类型信息,它常用于以下几种场景:
    • 判断一个对象的动态类型,即运行时的实际类型,而不是静态类型,即编译时的声明类型,例如:
      class Base { virtual void foo() {} };
      class Derived : public Base {};
      Base* p = new Derived();
      std::cout << typeid(p).name() << std::endl; // 输出Base*
      std::cout << typeid(*p).name() << std::endl; // 输出Derived
      
    • 比较两个表达式或者类型是否相同,例如:
      int x = 0;
      double y = 0.0;
      std::cout << std::boolalpha;
      std::cout << (typeid(x) == typeid(y)) << std::endl; // 输出false
      std::cout << (typeid(x) == typeid(int)) << std::endl; // 输出true
      
    • 获取一个表达式或者类型的名称,但是这个名称是由编译器实现定义的,不一定是可读的或者一致的,例如:
      std::cout << typeid(std::string).name() << std::endl; // 输出std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >
      
  • typeof:这个关键字可以用来在编译时推导出一个表达式的类型,它常用于以下几种场景:
    • 声明一个变量,但不知道它的确切类型,只知道它和另一个表达式的类型相同,例如:
      int x = 0;
      typeof(x) y = x; // y的类型和x的类型相同
      
    • 声明一个函数的返回类型,但不知道它的确切类型,只知道它和函数体中某个表达式的类型相同,例如:
      int foo();
      typeof(foo()) bar(); // bar的返回类型和foo的返回类型相同
      
    • 声明一个模板参数的类型,但不知道它的确切类型,只知道它和模板类或函数中某个表达式的类型相同,例如:
      template<typename T>
      struct Node
      {
          T data;
          typeof(data)* next; // next的类型和data的类型相同
      };
      

每天5分钟了解现代C++新特性 - 第4章 decltype说明符_哔哩哔哩_bilibili

  • 27
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

aFakeProgramer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值