[C++11]常量表达式函数

Posted Wecccccccc

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[C++11]常量表达式函数相关的知识,希望对你有一定的参考价值。

constexpr修饰函数。

普通函数/类成员函数。

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

代码如下:

#include <iostream>
using namespace std;

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


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

2.函数在使用之前,必须有对应的定义语句。

代码如下:

#include <iostream>
using namespace std;

constexpr int func1();

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

	return 0;
}

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

在测试程序constexpr int a = func1();中,还没有定义func1()就直接调用了,应该将func1()函数的定义放到main函数的上边。

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

代码如下:

#include <iostream>
using namespace std;

//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);
}

因为func1()是一个常量表达式函数,在函数体内部是不允许出现非常量表达式以外的操作,因此函数体内部的for循环是一个非法操作。

代码如下:

#include <iostream>
using namespace std;

//OK
class Test
{
public:
	constexpr int func()
	{
		constexpr int var = 100;
		return 5 * var;
	}
};

int main()
{
	Test t;
	constexpr int num = t.func();
	cout << "num = " << num << endl;
	return 0;
}

模板函数。

C++11语法中,constexpr可以修饰模板函数,但由于模板中类型的不确定性,因此模板函数实例化后的函数是否符合常量表达式函数的要求也是不确定的。
如果constexpr修饰的模板函数实例化结果不满足常量表达式函数的要求,则constexpr会被自动忽略,即该函数就等同于一个普通函数。

代码如下:

#include <iostream>
using namespace std;

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

template <typename T>
constexpr T display(T t)
{
	return t;
}

int main()
{
	Person p{ "Tom",18 };
	Person ret = display(p);//非常量表达式  普通函数

	cout << "name = " << ret.name << " age = " << ret.age << endl;

	constexpr Person p1{ "Jack",19 };
	constexpr Person ret1 = display(p1);//常量表达式函数

	cout << "name = " << ret1.name << " age = " << ret1.age << endl;

	constexpr int ret2 = display(250);//常量表达式函数
	cout << ret2 << endl;


	return 0;
}

测试结果:

类的构造函数。

如果想用直接得到一个常量对象,也可以用constexpr修饰一个构造函数,这样就可以得到一个常量构造函数。

常量构造函数要求:
构造函数的函数体必须为空,并且用初始化列表的方式为各个成员赋值。

代码如下:

#include <iostream>
using namespace std;

//error
/*struct Person
{

	Person(const char *name, int age) :name(name), age(age) {}
	const char *name;
	int age;
};*/

struct Person
{

	constexpr Person(const char *name,int age):name(name),age(age){}
	const char *name;
	int age;
};

int main()
{
	constexpr  Person p("Tom", 18);
	cout << "name = " << p.name << " age = " << p.age << endl;
	return 0;
}

测试结果:
在这里插入图片描述

以上是关于[C++11]常量表达式函数的主要内容,如果未能解决你的问题,请参考以下文章

inline内联函数

C++11新特性:16—— C++11 constexpr:验证是否为常量表达式(长篇神文)

C ++ 11中的常量表达式中是不是允许逗号运算符?

C++ const int 在常量表达式中不可用

C++11之常量表达式(const与constexpr的区别)

constexpr