首页 > 其他分享 >constexpr关键字

constexpr关键字

时间:2023-12-04 17:15:35浏览次数:26  
标签:const 函数 关键字 int constexpr 修饰 常量

文章参考:爱编程的大丙 (subingwen.cn)

1. const关键字

const关键字的判断:

  • 限制为常量。只有在声明时使用字面量初始化的才是常量,可以进入符号表

    void func(const int a){		// 只读变量
        ...
    }
    int x = 0;
    const int a = x;		// 只读变量
    const int b = 10;		// 常量
    
  • 说明变量是只读变量。不使用字面量初始化的const常量都是只读变量

  • 使用volatile修饰的const常量不会进入符号表。

在实际使用中,只读变量常量的作用并不一致,而编译器对于在编译期间不能确定初始值的const标识符,都作为只读变量处理。

这就容易导致二义性的出现。因此C++11提供了新的关键字:constexpr,用于专门修饰常量表达式。

2. constexpr关键字

2.1 概述

constexpr被专门用于修饰常量表达式(就是由多个常量组成并在编译阶段就确认得到计算结果的表达式)。

通过使用constexpr来定义常量,const就可以被用于定义只读变量,从而避免二义性(当然,依旧可以使用const定义常量,但不推荐)。

2.2 语法

constexpr可以直接修饰C++内置类型的数据。但如果是自定义类型(struct/class),不能直接constexpr修饰:

int x = 0;				// 变量
constexpr int a = 10;	// 得到常量
constexpr int b = a+1;	// 得到常量
// 对于结构体
struct T{
    int a;
}
constexpr T t{1};		// 得到常量

2.3 修饰函数返回值

使用constexpr修饰的函数被称为常量表达式,它可以是:

  • 普通函数
  • 类成员函数
  • 类构造函数
  • 模板函数

constexpr不能随意修饰函数,必须满足以下条件:

  1. 函数必须有返回值,且返回值是常量表达式。

  2. 函数在使用前,必须有对应的定义语句,不能只有声明。

    constexpr int func();			
    constexpr int num = func();			// 这一句会报错,因为此时func()函数还没有定义,只有声明
    constexpr int func(){
        return 10;
    }
    
  3. 函数的函数体中,不能出现非常量表达式之外的语句。以下几条语句除外:

    • typedef
    • using:功能和typedef一致。
    • static_assert:断言。
    • return
    constexpr int func(){
        using type = int;
        constexpr type a = 10;
        constexpr type b = 20;
        return a * b;
    }
    

    2.4 修饰模板函数

    由于模板函数中数据类型的不确定性,函数模板实例化后的模板函数是否复合常量表达式函数的标准也不确定。因此,constexpr是是否生效取决于模板实例化情况。

    #include <iostream>
    using namespace std;
    
    struct Person {
        const char* name;
        int age;
    };
    
    // 定义函数模板
    template<typename T>
    constexpr T dispaly(T t) {
        return t;
    }
    
    int main()
    {
        struct Person p { "luffy", 19 };
        //普通函数
        struct Person ret = dispaly(p);
        cout << "luffy's name: " << ret.name << ", age: " << ret.age << endl;
    
        //常量表达式函数
        constexpr int ret1 = dispaly(250);
        cout << ret1 << endl;
    
        constexpr struct Person p1 { "luffy", 19 };
        constexpr struct Person p2 = dispaly(p1);
        cout << "luffy's name: " << p2.name << ", age: " << p2.age << endl;
        return 0;
    }
    
    • 19行:由于p不是常量,不符合常量表达式函数的标准,因此constexpr失效。
    • 23行:250是常量,符合常量表达式函数的标准,因此constexpr生效,得到的ret1也是常量。
    • 27行:p1是常量,符合常量表达式函数的标准,因此constexpr生效,得到的p2也是常量。

    2.4 修饰构造函数

    如果想直接得到一个常量对象,可以直接使用constexpr修饰构造函数,这样可以得到一个常量构造函数,前提是:

    • 常量构造函数的函数体必须为空,并且采用成员初始化列表来初始化数据成员。
    #include <iostream>
    using namespace std;
    
    struct Person {
        const char* name;
        int age;
        constexpr Person(const char* p, int age) :name(p), age(age){}
    };
    
    int main()
    {
        constexpr struct Person p1("luffy", 19);
        cout << "luffy's name: " << p1.name << ", age: " << p1.age << endl;
        return 0;
    }
    

标签:const,函数,关键字,int,constexpr,修饰,常量
From: https://www.cnblogs.com/beasts777/p/17875404.html

相关文章

  • nullptr关键字
    文章参考:爱编程的大丙(subingwen.cn)C使用NULL表示空,其定义为:#defineNULL((void*)0)在C++中同样定义了NULL,C和C++虽然都是强类型语言,但是C++对语言的要求更高,不允许(void*)类型进行隐式的类型转化,因此如果沿袭C中NULL的定义,那么下述代码会出错:int*p=NULL;因此C++......
  • c++ friend关键字 友元
     在C++中,friend关键字用于声明友元函数或友元类1。友元函数或友元类可以访问当前类的私有成员和保护成员,即使它们不是当前类的成员函数或成员类1。友元函数是一个独立的函数,而友元类是一个类可以访问另一个类的私有成员和保护成员1。例如,如果要声明函数为一个类的友元,需要......
  • 学C笔记归纳 第四篇——static关键字(重点)
    C语言本身内置了关键字,并非自己创建,也不能自己创建。static的功能:static功能修饰局部变量转变储存位置,延长局部变量生命周期,也可以保持其值不变修饰全局变量将外部链接属性变为内部连接属性,使作用域变小,其他源文件(.c)就不能再使用这个全局变量了,增加程序安全性模块内函......
  • centos查看日志文件内容,包含某个关键字的前后5行日志内容
    简述centos查看日志的几种方法centos查看日志文件内容,包含某个关键字的前后5行日志内容前情提示系统:一说部分截图、链接等因过期、更换域名、MD语法等可能不显示,可联系反馈(备注好博文地址),谢谢❤带有#号、删除线、不操作、不执行字样的为提示或者备份bash,实际不执行如果无法下载......
  • 【PUSDN】centos查看日志文件内容,包含某个关键字的前后5行日志内容,centos查看日志的几
    简述centos查看日志的几种方法centos查看日志文件内容,包含某个关键字的前后5行日志内容前情提示系统:一说部分截图、链接等因过期、更换域名、MD语法等可能不显示,可联系反馈(备注好博文地址),谢谢❤带有#号、删除线、不操作、不执行字样的为提示或者备份bash,实际不执行如果无法下载......
  • Angular Component 内 set 关键字的使用
    "set"关键字在Angular组件的TypeScript代码中通常用于创建和定义类的属性的setter方法。它是一种特殊的方法,负责设置类的私有成员变量的值。通过使用"set"关键字,我们可以在设置属性值时执行一些额外的逻辑,如输入验证、触发事件等。让我们通过一个简单的例子来说明"set"关键字的......
  • 关键字 开发-09 validate断言
    1.yaml文件中添加validate进行接口断言首先我们在utils/validate.py文件添加需要的断言方式importredefequals(check_value,expect_value):assertcheck_value==expect_value,f'{check_value}=={expect_value}'defless_than(check_value,expect_value):......
  • 关键字 开发-08 extract提取返回的结果
    1.extract提取请求返回结果的返回值在进行接口自动化的时候,往往需要提取上一个接口返回的值,传递给下一个接口使用。创建utils/extract.pyimportjsonimportreimportjsonpathimportjmespathfromutilsimportexceptionsfromrequestsimportResponsedefextract_b......
  • instanceof关键字
    instanceof用于判断类型eg:catinstanceofAnimal判断该对象引用,是否是为该类型(自身类、自身类父类、Object)都是返回true,其他情况返回falseeg:strinstanceofString例子AnimalParent类publicclassAnimalParent{}Cat类publicclassCatextendsAnimalParent......
  • SQL 关键字执行顺序
    1.FromandJOIN首先我们进行查询的时候,肯定是先获得一份数据集的,From语句和JOIN被先执行的,就是为了获得数据集的。2.WHERE一旦数据集给拿到了,WHERE限制条件会被用到某些行上,并把不满足的行给抛弃掉。并且,这能够用到各种数据类型中3.GROUPBYWHERE条件限定之后,接下来就是GRO......