栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

条款15:只要有可能使用constexpr,就使用他

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

条款15:只要有可能使用constexpr,就使用他

constexpr当它应用与对象时,其实就是一个加强版const;但是应用于函数时,却有着相当不同的意义;

constexpr 对象:

constexpr对象具备const属性,在编译阶段已知

int sz;							// 非constexpr变量
constexpr auto arryaSize1 = sz; // 错误!sz的数值在编译器未知
std::array data1;		// 错误!sz的数值在编译器未知
constexpr auto arraySize2 = 10; // 没问题,10为编译器常量
std::array data2; // 没问题,arraySize2是个constexpr

注意:const并未提供和consexpr同样的保证,因为const对象不一定经由编译器已知值来初始化;

int sz;							// 非constexpr变量
const auto arryaSize1 = sz;     // 没问题!arraySize是sz的一个const副本
std::array data1;		// 错误!arryaSize1的数值在编译器未知

一言以蔽之,所有constexpr对象都是const对象,但是所有的const对象并非都是constexpr对象。如果你想让编译器提供保证,让变量拥有一个值,用于要求编译器期常量的语境,那么能达到这个目的的工具是constexpr,而非const

constexpr函数
  • constexpr函数可以用在要求编译器常量的语境当中。若你传给一个constexpr函数的实参数值是在编译期已知,则结果也会在编译期间计算出来
  • 在调用constexpr函数时,若传入的数值有一个或者多个在编译器未知,则它的运作方式和普通函数无差异

考虑一个pow函数

constexpr int pow(int base, int exp) noexcept {		// pow是一个constexpr函数,且不会抛出异常
	// ....
}

constexpr auto numConds = 5;
std::array results;		   // results有3^numConds个元素

pow前面写的那个constexpr并不表明pow要返回一个const数值,它表明的是如果base和expr是编译器常量,pow的反馈结果就可以当一个编译器常量使用。如果base和expr中有一个不是编译器常量,则pow的返回结果就将在执行期计算。

在C++11中,constexpr函数不得包含多于一个可执行语句,即一个return语句。我们可以用条件运算符和递归解决这个问题

// C++11
constexpr int pow(int base, int exp) noexcept {
    return (exp == 0 ? 1 : base * pow(base, exp - 1));
}

C++14限制条件放宽了,下列代码在C++11中编译不过

constexpr int pow(int base, int exp) noexcept {
    int result = 1;
    for (int i = 0; i < exp; i++) {
        result *= base;
    }
    return result;
}

// 后面没太看明白用处

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/289660.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号