[c++] constexpr and literal class
一、C++ const 和 constexpr 的区别?
constexpr 表示这玩意儿在编译期就可以算出来(前提是为了算出它所依赖的东西也是在编译期可以算出来的)。
const 只保证了运行时不直接被修改(但这个东西仍然可能是个动态变量)。
constexpr 是 C++11 引入的,一方面是为了引入更多的编译时计算能力,另一方面也是解决 C++98 的 const 的双重语义问题。
const修饰的是类型,constexpr修饰的是用来算出值的那段代码。
在 C 里面,const 很明确只有「只读」一个语义,不会混淆。C++ 在此基础上增加了「常量」语义,也由 const 关键字来承担,引出来一些奇怪的问题。C++11 把「常量」语义拆出来,交给新引入的 constexpr 关键字。
二、为什么用 constexpr
预判错误
int i; // not constant
const int size = i; // fine! 可以,但为什么不在这里就先判断出问题的隐患呢? int arr[size]; // Error!
然而对于constexpr,则表明这个值不仅是constant的,而且也是编译期确定的
int i; // not constant
constexpr int size = i; // Error!
于是,constexpr修饰的变量是可以表示数组大小的。
数组初始化
constexpr可以用来修饰变量、函数、构造函数。一旦以上任何元素被constexpr修饰,那么等于说是告诉编译器 “请大胆地将我看成编译时就能得出常量值的表达式去优化我”。编译器优化过程中便会发现错误。
const int func() {
return ;
}
main(){
int arr[func()];
}
//error : 函数调用在常量表达式中必须具有常量值
告诉编译器返回的是个“常数”,所以,不会报错了。
constexpr func() {
return ;
}
main(){
int arr[func()];
}
//编译通过
为了性能
int main()
{
int i;
cin >> i;
int arr[i];
}
跟const无关,而是使用了C99的一个特性,名叫variable length array(简称VLA)。
而为什么我们需要constexpr呢?那就是为了性能。
其他链接
When should you use constexpr capability in C++11?
When should literal classes be used in C++?
Want speed? Use constexpr meta-programming! [static的方式是最快的]
三、字面类型 (LiteralType)
字面量 类型
Ref: C++ literal type
要区分 literal 和 literal-type 这两个不同的概念。
literal:文字量,10,3.14, true ,u8"123", L"好"这些东西。
literal-type: 参考http://en.cppreference.com/w/cpp/concept/LiteralType 简单的说,就可以在用于编译期运算的对象。
标量 类型
对于标量,例如int,显然可以参与 编译期运算,例如:constexpr int fac( int N); //计算阶乘。所以标量都是属于literal-type。
从这里可以看出,literal-type仅仅是类型系统中,一个catalog。所有的类型,要么归类到literal-type,要么归类到none-literal-type。
现在class,也能归类于literal-type,只要满足一些条件:
是否是 literal type?
// is_literal_type example
#include <iostream>
#include <type_traits> struct A { };
struct B { ~B(){} }; int main() {
std::cout << std::boolalpha;
std::cout << "is_literal_type:" << std::endl;
std::cout << "int: " << std::is_literal_type<int>::value << std::endl;
std::cout << "int&: " << std::is_literal_type<int&>::value << std::endl;
std::cout << "int*: " << std::is_literal_type<int*>::value << std::endl;
std::cout << "A: " << std::is_literal_type<A>::value << std::endl;
std::cout << "B: " << std::is_literal_type<B>::value << std::endl;
return ;
}
Output:
is_literal_type:
int: true
int&: true
int*: true
A: true
B: false
End.
[c++] constexpr and literal class的更多相关文章
- [Code::Blocks] Install wxWidgets & openCV
The open source, cross platform, free C++ IDE. Code::Blocks is a free C++ IDE built to meet the most ...
- 本人SW知识体系导航 - Programming menu
将感悟心得记于此,重启程序员模式. js, py, c++, java, php 融汇之全栈系列 [Full-stack] 快速上手开发 - React [Full-stack] 状态管理技巧 - R ...
- Item 15: 只要有可能,就使用constexpr
本文翻译自modern effective C++,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 如果说C++11中有什么新东西能拿"最佳困惑奖" ...
- c++ 11 游记 之 decltype constexpr
title: c++ 11 游记 1 keyword :c++ 11 decltype constexpr 作者:titer1 zhangyu 出处:www.drysaltery.com 联系:130 ...
- C++11特性——变量部分(using类型别名、constexpr常量表达式、auto类型推断、nullptr空指针等)
#include <iostream> using namespace std; int main() { using cullptr = const unsigned long long ...
- format not a string literal and no format arguments
今天cocos2d-x打包 android的时候报错:format not a string literal and no format arguments 报错点是:__String::create ...
- Android studio2.2 ndk 错误 :format not a string literal and no format arguments!
在Android Studio2.2 进行NDK编程,在对*char 字符串 进行日志输出时,报错: error: format not a string literal and no format ...
- asp.net Literal
常用于动态向页面添加内容 Panel panel = new Panel(); Literal literal = new Literal(); literal.Text = "<br ...
- C++11:新式的字符串字面常量(String Literal)
自C++11起,我们可以定义 raw string 字符串字面常量. Raw string 允许我们定义所见即所得的字符串字面常量,从而可以省下很多用来修饰特殊 字符的符号. Raw string 以 ...
随机推荐
- 关于MVC的开源商城 Nop之闲聊
nopcommerce是国外的一个高质量的开源b2c网站系统,基于EntityFramework4.0和MVC3.0,使用Razor模板引擎,有很强的插件机制,包括支付配送功能都是通过插件来实现的,基 ...
- Google Protocol Buffer开发环境搭建注意事项
PB的安装配置基本上依照网上的教程做就没什么问题:有一点要注意到是当遇到libcmt.lib或msvcrt.lib等lib库与PB中的库冲突时,一定要检查工程的编译方式完全一致,整个项目当中都要注意这 ...
- Matlab 视频与图像之间的相互转换
matlab版本是2015b,其中更新了部分函数库之前网上相关程序不适用于新版本,在此提供适用于新版本的程序: 帧序列转换为视频 function video = frames2video(frame ...
- php面试 1013总结
面试题1:http://www.docin.com/p-288430879.html 数据库优化: session和cookies区别 缓存系统有哪些 myisam和InDB读写区别 varchar和 ...
- MVC自定义分页(附表跳转页Loading提示)
之前我发表了一篇MVC无刷新分页的文章,里面用的是MvcPager控件,但是那个受那个控件限制,传值只能用PagedList,各方面都受到了限制,自由度不够高,现在还是做MVC无刷新分页,但是想直接用 ...
- 带额外toggle()功能的jquery库
<html><head><meta http-equiv="Content-Type" content="text/html;charset ...
- SQL Server 高级sql总结
----------------------------------------------------------------------Select------------------------ ...
- Google云平台对于2014世界杯半决赛的预测,德国阿根廷胜!
由于本人是个足球迷,前段日子Google利用自己云平台预测世界杯八进四的比赛并取得了75%的正确率的事情让我振动不小.虽然这些年一直听说大数据的预测和看趋势能力如何如何强大,但这次的感受更加震撼,因为 ...
- 非域环境下搭建自动故障转移镜像无法将 ALTER DATABASE 命令发送到远程服务器实例的解决办法
非域环境下搭建自动故障转移镜像无法将 ALTER DATABASE 命令发送到远程服务器实例的解决办法 环境:非域环境 因为是自动故障转移,需要加入见证,事务安全模式是,强安全FULL模式 做到最后一 ...
- VS轻松开发Node.js应用
PTVS开发团队又开发出一款可以在VS里编写Node.js应用程序的插件--NTVS(Node.js Tools for Visual Studio),开发者可以在VS里轻松开发Node.js应用. ...