C++ decltype 说明符

目录
  • 1.语法
  • 2.关键词decltype

1.语法

decltype ( 实体 ) (1) (C++11 起)
decltype ( 表达式 ) (2) (C++11 起)

解释:

1) 如果实参是没有括号的标识表达式或没有括号的类成员访问表达式,那么 decltype 产生以该表达式命名的实体的类型。如果没有这种实体或该实参指名了一组重载函数,那么程序非良构。

  • 如果实参是指名某个结构化绑定的没有括号的标识表达式,那么 decltype 产生其被引用类型(在关于结构化绑定声明的说明中有所描述)。
  • 如果实参是指名某个非类型模板形参的没有括号的标识表达式,那么 decltype 生成该模板形参的类型(当该模板形参以占位符类型声明时,类型会先进行任何所需的类型推导)。

2) 如果实参是其他类型为 T 的任何表达式,且

  • 如果 表达式 的值类别是亡值,将会 decltype 产生 T&&;
  • 如果 表达式 的值类别是左值,将会 decltype 产生 T&;
  • 如果 表达式 的值类别是纯右值,将会 decltype 产生 T。

如果 表达式 是返回类类型纯右值的函数调用,或是右操作数为这种函数调用的逗号表达式,那么不会对该纯右值引入临时量。

如果 表达式 是除了(可带括号的)立即调用以外的 (C++20 起)纯右值,那么不会从该纯右值实质化临时对象:即这种纯右值没有结果对象。

该类型不需要是完整类型或拥有可用的析构函数,而且类型可以是抽象的。此规则不适用于其子表达式:decltype(f(g())) 中,g() 必须有完整类型,但 f() 不必。

注意:

  • 如果对象的名字带有括号,那么它会被当做通常的左值表达式,从而 decltype(x) 和 decltype((x)) 通常是不同的类型。
  • 在难以或不可能以标准写法进行声明的类型时,decltype 很有用,例如 lambda 相关类型或依赖于模板形参的类型。

2.关键词decltype

示例:

#include <iostream>
#include <type_traits>

struct A { double x; };
const A* a;

decltype(a->x) y;       // y 的类型是 double(其声明类型)
decltype((a->x)) z = y; // z 的类型是 const double&(左值表达式)

template<typename T, typename U>
auto add(T t, U u) -> decltype(t + u) // 返回类型依赖于模板形参
{                                     // C++14 开始可以推导返回类型
    return t+u;
}

int main()
{
    int i = 33;
    decltype(i) j = i * 2;

    std::cout << "i = " << i << ", "
              << "j = " << j << '\n';

    std::cout << "i 和 j 的类型相同吗?"
              << (std::is_same_v<decltype(i), decltype(j)> ? "相同" : "不同") << '\n';

    auto f = [](int a, int b) -> int
    {
        return a * b;
    };

    decltype(f) g = f; // lambda 的类型是独有且无名的
    i = f(2, 2);
    j = g(3, 3);

    std::cout << "i = " << i << ", "
              << "j = " << j << '\n';
}

输出:

i 和 j 的类型相同吗?相同
i = 33, j = 66
i = 4, j = 9

到此这篇关于C++ decltype 说明符的文章就介绍到这了,更多相关decltype 说明符内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C++11新特性中auto 和 decltype 区别和联系

    C++11新特性中auto 和 decltype 区别和联系 一. auto简介 编程时候常常需要把表达式的值付给变量,需要在声明变量的时候清楚的知道变量是什么类型.然而做到这一点并非那么容易(特别是模板中),有时候根本做不到.为了解决这个问题,C++11新标准就引入了auto类型说明符,用它就能让编译器替我们去分析表达式所属的类型.和原来那些只对应某种特定的类型说明符(例如 int)不同.auto 让编译器通过初始值来进行类型推演.从而获得定义变量的类型,所以说 auto 定义的变量必须有初始

  • C++ decltype用法举例说明

    1.什么是decltype decltype是C++11新增的一个关键字,和auto的功能一样,用来在编译时期进行自动类型推导.引入decltype是因为auto并不适用于所有的自动类型推导场景,在某些特殊情况下auto用起来很不方便,甚至压根无法使用. 对于内置类型的对象,使用decltype很直观,但当参数为复合类型的时候就应该注意一些使用细节问题. auto varName=value; decltype(exp) varName=value; auto根据=右边的初始值推导出变量的类型,

  • C++11特性小结之decltype、类内初始化、列表初始化返回值

    作用:返回表达式或变量的类型 返回值规则: 若e是一个左值(lvalue,即"可寻址值"),则decltype(e)将返回T& 若e是一个临终值(xvalue),则返回值为T&& 若e是一个纯右值(prvalue),则返回值为T decltype()不会执行括号内的表达式,decltype返回的类型是用于声明的,不能用于单纯的判断.比如decltype(a)==int,是不可以的,只能是在定义新的变量.返回值的地方使用: int a=1; decltype(a)

  • C++ decltype类型说明符

    1 基本语法 decltype 类型说明符生成指定表达式的类型.在此过程中,编译器分析表达式并得到它的类型,却不实际计算表达式的值. 语法为: decltype( expression ) 编译器使用下列规则来确定expression 参数的类型. 如果 expression 参数是标识符或类成员访问,则 decltype(expression) 是 expression 命名的实体的类型.如果不存在此类实体或 expression 参数命名一组重载函数,则编译器将生成错误消息. 如果 expr

  • c++ decltype关键字的用法

    1. decltype关键字的用途是什么 给定变量的名称或者表达式,decltype返回变量或者表达式的类型.如下所示: const int i = 0; // decltype(i) is const int bool f(const Widget& w); // decltype(w) is const Widget&,decltype(f) is bool(const Widget&) struct Point { int x, y; // decltype(Point::x

  • C++ decltype 说明符

    目录 1.语法 2.关键词decltype 1.语法 decltype ( 实体 ) (1) (C++11 起) decltype ( 表达式 ) (2) (C++11 起) 解释: 1) 如果实参是没有括号的标识表达式或没有括号的类成员访问表达式,那么 decltype 产生以该表达式命名的实体的类型.如果没有这种实体或该实参指名了一组重载函数,那么程序非良构. 如果实参是指名某个结构化绑定的没有括号的标识表达式,那么 decltype 产生其被引用类型(在关于结构化绑定声明的说明中有所描述)

  • C++11之后的decltype类型指示符详解

    目录 一.什么是decltype类型指示符 二.typeid运算符 三.使用decltype指示符 四.decltype和引用 五.decltype(auto) 六.本章代码汇总 一.什么是decltype类型指示符 有时会遇到这种情况:希望从表达式的类型推断出要定义的变量的类型,但是不想用该表达式的值初始化变量.为了满足这一要求,C++11 新标准引入了另一种类型说明符 decltype ,它的作用是选择并返回操作数的数据类型.在此过程中,编译器分析表达式并得到它的类型,却并不实际计算表达式的

  • C++中的Lambda表达式及表达式语句

    目录 一.概念 二.左值与右值 三.类型转换 四.操作符 五.思考 1.思考下面x变量是左值还是右值,有什么特性? 2.思考一下以下赋值操作符的原始代码是怎样的? 3.思考以下代码做了什么事情? 一.概念 定义:表达式由一到多个操作数组成,可以求值并通常会返回求值结果: 最基本表达式:变量.字面值,通常包含操作符: 操作符特性: 1.接收几个操作数:一元.二元.三元: 2.对类型有要求(可能涉及类型转换): 3.操作数是左值还是右值: 4.结果的类型: 5.结果是左值还是右值: 6.优先级与结合

  • 详解C++中的左值,纯右值和将亡值

    目录 引入 一.表达式 二.值类别 三.左值 四.纯右值 五.将亡值 六.注意 引入 C++中本身是存在左值,右值的概念,但是在C11中又出现了左值,纯右值,将亡值得概念:这里我们主要介绍这些值的概念. 一.表达式 定义:由运算符和运算对象构成的计算式(类似数学中的算术表达式) 每个 C++ 表达式(带有操作数的操作符.字面量.变量名等)可按照两种独立的特性加以辨别:**类型和值类别 **(value category).每个表达式都具有某种非引用类型,且每个表达式只属于三种基本值类别中的一种:

  • 详谈c++11 final与override说明符

    如下所示: //final,override出现在形参列表以及尾置返回类型之后 #include <iostream> using namespace std; struct B{ virtual void f1(int) const; virtual void f2(int); void f3(int) final;//出错,final不能修饰非虚函数 }; struct D:B{ void f1(int) const override ;//去掉const将出错,必须和基类中的函数原型一致

  • C++派生访问说明符小记(推荐)

    如下所示: #include <iostream> using namespace std; class a{ protected: int i; private: int j; public: int k; }; class b:public a{//派生访问说明符对派生类内对其直接基类的访问没有影响,主要是用于控制派生类用户(包括派生类的派生类)对基类成员的访问权限 friend void f1(a a1){ cout<<a1.i;//错误,派生类的成员或友元不能访问基类对象p

  • 详解C++成员函数的override和final说明符的用法

    override 说明符 可使用 override 关键字来指定在基类中重写虚函数的成员函数. 语法 function-declaration override; 备注 override 仅在成员函数声明之后使用时才是区分上下文的且具有特殊含义:否则,它不是保留的关键字. 使用 override 有助于防止您的代码中出现意外的继承行为.以下示例演示在未使用 override 的情况下,可能不打算使用派生类的成员函数行为.编译器不会发出此代码的任何错误. class BaseClass { vir

  • C++ auto类型说明符

    编程时常常需要把表达式的值赋给变量,这就要求在声明变量的时候清楚知道表达式的类型.然而要做到这一点并非那么容易,有时候甚至根本做不到.为了解决这个问题,C++11标准引入了auto类型说明符,用它就能让编译器替我们去分析表达式所属的类型. 与原来那些只对应一种特定类型的说明符不同,auto让编译器通过初值来推算变量类型.显然,auto定义的变量必须要有初始值. 使用auto具有以下几点好处: 可靠性:如果表达式的类型发生更改(包括函数返回值发生更改的情况),它也能工作. 性能:确保将不会进行转换

随机推荐