编辑代码

#include <iostream>
using namespace std;

void func(const int num)
{
    int a1=520;
    int a2=250;
    const int count=24;
    int arrar[count];  //可以count是常量
    //int arrar[num];  //err 这里的num是变量只读而不是常量

}
// C++ 程序从编写完毕到执行分为四个阶段:预处理、 编译、汇编和链接 4 个阶段,得到可执行程序之后就可以运行了。需要额外强调的是,常量表达式和非常量表达式的计算时机不同,非常量表达式只能在程序运行阶段计算出结果,但是常量表达式的计算往往发生在程序的编译阶段,这可以极大提高程序的执行效率,因为表达式只需要在编译阶段计算一次,节省了每次程序运行时都需要计算一次的时间。

struct T
{
    int a;
};

//常量表达式函数
//1函数必须要有返回值,并且返回的表达式必须是常量表达式。

// error,不是常量表达式函数
// constexpr void func1()
// {
//     int a = 100;
//     cout << "a: " << a << endl;
// }

// error,不是常量表达式函数
// constexpr int func1()
// {
//     int a = 100;
//     return a;
// }


//常量函数在调用之前,必须要有对应的定义语句。


// constexpr int func1();
// int main()
// {
//     constexpr int num = func1();	// error
//     return 0;
// }

// constexpr int func1()
// {
//     constexpr int a = 100;
//     return a;
// }

//3整个函数的函数体中,不能出现非常量表达式之外的语句(using 指令、typedef 语句以及 static_assert 断言、return 语句除外)。

// error
// constexpr int func1()
// {
//     constexpr int a = 100;
//     constexpr int b = 10;
//     for (int i = 0; i < b; ++i)
//     {
//         cout << "i: " << i << endl;   //进行了循环。
//     }
//     return a + b;
// }

// ok
constexpr int func2()
{
    using mytype = int;
    constexpr mytype a = 100;
    constexpr mytype b = 10;
    constexpr mytype c = a * b;
    return c - (a + b);
}

//修饰模板函数

struct Person
{
    const char *name;
    int age;
};

//定义函数模板
template<typename T>
constexpr T dispaly(T  t)
{
    return t;
}

void test1()
{
    struct Person p { "luffy", 19 };
    //普通函数
    struct Person ret = dispaly(p);
    cout << "luffy's name: " << ret.name << ", age: " << ret.age << endl;
    ret.age=20;   //ok 说明返回的不是常量
    //常量表达式函数
    constexpr int ret1 = dispaly(250);
    cout << ret1 << endl;
    //ret1=20;

    constexpr struct Person p1 { "luffy", 19 };
    constexpr struct Person p2 = dispaly(p1);
    cout << "luffy's name: " << p2.name << ", age: " << p2.age << endl;
    //p2.age=20;  err
}
int main() {
    constexpr T t{100};  //{}为初始化列表
    // t.a=10;  err
    test1();
    return 0;


}