一、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()];
}
//编译通过

为了性能

放在 stack上的数组也是可以的,比如main中的如下:
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的更多相关文章

  1. [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 ...

  2. 本人SW知识体系导航 - Programming menu

    将感悟心得记于此,重启程序员模式. js, py, c++, java, php 融汇之全栈系列 [Full-stack] 快速上手开发 - React [Full-stack] 状态管理技巧 - R ...

  3. Item 15: 只要有可能,就使用constexpr

    本文翻译自modern effective C++,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 如果说C++11中有什么新东西能拿"最佳困惑奖" ...

  4. c++ 11 游记 之 decltype constexpr

    title: c++ 11 游记 1 keyword :c++ 11 decltype constexpr 作者:titer1 zhangyu 出处:www.drysaltery.com 联系:130 ...

  5. C++11特性——变量部分(using类型别名、constexpr常量表达式、auto类型推断、nullptr空指针等)

    #include <iostream> using namespace std; int main() { using cullptr = const unsigned long long ...

  6. format not a string literal and no format arguments

    今天cocos2d-x打包 android的时候报错:format not a string literal and no format arguments 报错点是:__String::create ...

  7. 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  ...

  8. asp.net Literal

    常用于动态向页面添加内容 Panel panel = new Panel(); Literal literal = new Literal(); literal.Text = "<br ...

  9. C++11:新式的字符串字面常量(String Literal)

    自C++11起,我们可以定义 raw string 字符串字面常量. Raw string 允许我们定义所见即所得的字符串字面常量,从而可以省下很多用来修饰特殊 字符的符号. Raw string 以 ...

随机推荐

  1. C#判断数组是否为空

    string[] array=new[] { "1", "2", "3", "4", "5" }; ...

  2. (转)C# XMPP客户端与openfire通信(Matrix Xmpp 授权破解教程)

    FROM:http://www.cnblogs.com/crabo/p/CRACK_MATRIX_XMPP.html 如此著名的XMPP , 居然试过jabber-net, agsXmpp,matri ...

  3. cordova插件开发注意事项

    1. 编写插件,先创建好cordova项目之后,在项目里开发调试好在去创建插件目录 如何在cordova项目里创建呢,在android文件夹下面的res/xml/config.xml里去加入插件 例如 ...

  4. sqlmap用户手册 | WooYun知识库

    sqlmap用户手册 说明:本文为转载,对原文中一些明显的拼写错误进行修正,并标注对自己有用的信息. 原文:http://drops.wooyun.org/tips/143  ============ ...

  5. phpexcel读取excel的xls xlsx csv格式

    我之前写过一篇PHP读取csv文件的内容 上代码index.php <?php /** * * @author XC * */ class Excel { public $currentShee ...

  6. 简单正则匹配QQ邮箱

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <script src ...

  7. .net 下新版highcharts本地导出图片bug处理

    最近公司要用到highcharts这个插件来生成图表,所以我花了点时间研究了下. 现在最新的版本是3.0.2,这js插件居多优点就不比多说了,demo官网上也很详细.但是优点不爽的地方是,导出图片这个 ...

  8. Powershell 十个常见任务

    学习Powershell的时候,基本的语法也了解了一些,但是就是不知道要写些什么?作为一个过来者,和大家一起分享下常见的几个管理任务脚本. 1.更改本地Administrator账号密码 [ADSI] ...

  9. 关于c++的 vector 容器的使用及创建方法

    1.vector向量容器的使用,vector具有自动管理的功能,可以进行元素的查找删除 创建方法: (1)  vector<int > v; 创建了一个v的容器,没指定容量: (2)  v ...

  10. Microsoft Avro介绍

    Microsoft发布了他们自己对Apache Avro通信协议的实现.Avro被描述为"紧凑的二进制数据序列化格式,类似于Thrift或者Protocol Buffers",同时 ...