c++11--常量表达式

1.常量表达式
1.1.引入背景

#include <iostream>

const int GetConst(){return 1;}
void Constless(int cond){
    //int arr[GetConst()] = {0};//err
    //enum{e1 = GetConst(), e2};//err
    switch(cond){
        //case GetConst()://err
            break;
        default:
            break;
    }
}

上述三处均无法使用GetConst(),因为const修饰的变量是运行期变量。
上述三处需要编译期常量。通过枚举,#define,字面常量可以得到编译期常量。

1.2.c++11引入constexpr
(1). 通过constexpr得到返回值是编译期常量的函数。

#include <iostream>

constexpr int GetConst(){return 1;}
void Constless(int cond){
    int arr[GetConst()] = {0};//ok
    enum{e1 = GetConst(), e2};//ok
    switch(cond){
        case GetConst()://ok
            break;
        default:
            break;
    }
}

使用constexpr修饰函数返回值时,对函数的要求:
a. 函数体只能包含单个语句,这个语句必须是return
b. 函数必须有返回值(void不算)。
c. 当在编译期通过函数调用取得编译期常量处,函数定义需可见。
d. return中的表达式需要是常量表达式。(当一个表达式的所有参与成员均是常量表达式时这个表达式整体是常量表达式)。

(2).如何判断单个成员构成常量表达式:
单个成员是enum值,#define值,字面常量,constexpr修饰的变量时。
constexpr修饰的变量必须使用常量表达式执行初始化。

(3).如何才能将自定义类型变量添加constexpr修饰

#include <iostream>

struct MyType{
    constexpr MyType(int x):i(x){}
    constexpr GetInt(){return i;}// 一个constexpr修饰的类型,其字段依然有constexpr性质。
    int i;
};

constexpr MyType mt = {0};
int main(){
    return 0;
}

需要为类型的构造函数添加constexpr修饰。
添加constexpr修饰的构造需满足:
a.函数体为空
b.接收的实参列表中每个实参需为常量表达式

(4). 模板推导下特殊处理说明

#include <iostream>
struct NotLiteral{
    NotLiteral(){i=5;}
    int i;
};

NotLiteral n1;
template<typename T>
constexpr T ConstExp(T t){
    return t;
}

void g(){
    NotLiteral n1;
    NotLiteral nl1 = ConstExp(n1);
    //constexpr NotLiteral n12 = ConstExp(n1);// err
    constexpr int a = ConstExp(1);
}

int main(){
    return 0;
}

上述模板函数ConstExp,预期返回值是常量表达式。
如果上述是一个非模板函数,则要求实参必须是常量表达式。
针对上述模板函数,做了特别处理:
实参是常量表达式时,返回值自然是常量表达式。
实参不是常量表达式时,不报错,返回值是非常量表达式。

  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

raindayinrain

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

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

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

打赏作者

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

抵扣说明:

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

余额充值