c++新特性实验(1)预处理
1.参考资料
1.1 C++
- C++17 标准文档(正式) : https://www.iso.org/standard/68564.html
- C++ 标准文档(草案) : http://www.open-std.org/JTC1/SC22/WG21/docs/standards#14882
- C++最新资讯,资料 : https://www.isocpp.org/
1.2 gcc对C++的支持
- gcc官网:
- gcc 各版本对c++新特性的支持情况 :
https://gcc.gnu.org/projects/cxx-status.html
2.__has_include(C++17 起)
2.1 作用
预编译函数. 结果仅表明指定名称的头或源文件 是否存在,并不是已经include过了的意思。
2.2 语法
__has_include ( " 文件名 " ) __has_include ( < 文件名 > )(C++17 起)
2.3 示例
has_inclue.cpp
//#include "has_include.h"
#if __has_include("has_include.h")
#define NUM 1
#else
#define NUM 0
#endif
#include <stdio.h>
#include <stdlib.h>
int main(int arg,char *argv[])
{
printf("num = %d\n",NUM);
return ;
}
- 第1行,只要在相应的目录中存在has_include.h文件,就返回true,与第1行的注释打开没有关系.删掉has_include.h后,NUM才是0.
- 程序在编译完成之后结果就已经确定,运行时动态删除,增加其参数中指定的文件,不会改变结果.
3.__has_cpp_attribute(C++20 起)
3.1 作用
检测标准属性是否存在,检测不了厂商自定义的属性.
attribute-token |
属性 |
值 | 标准 |
assert |
[[assert]] |
201806L | (C++20) |
carries_dependency |
[[carries_dependency]] |
200809L | (C++11) |
deprecated |
[[deprecated]] |
201309L | (C++14) |
ensures |
[[ensures]] |
201806L | (C++20) |
expects |
[[expects]] |
201806L | (C++20) |
fallthrough |
[[fallthrough]] |
201603L | (C++17) |
likely |
[[likely]] |
201803L | (C++20) |
maybe_unused |
[[maybe_unused]] |
201603L | (C++17) |
no_unique_address |
[[no_unique_address]] |
201803L | (C++20) |
nodiscard |
[[nodiscard]] |
201603L | (C++17) |
noreturn |
[[noreturn]] |
200809L | (C++11) |
unlikely |
[[unlikely]] |
201803L | (C++20) |
3.2 示例
#if __has_cpp_attribute // 检查 __has_cpp_attribute 是否存在
# if __has_cpp_attribute(deprecated) // 检查一个属性
# define DEPRECATED(msg) [[deprecated(msg)]]
# endif
#endif
#ifndef DEPRECATED
# define DEPRECATED(msg)
#endif
4.#line 增大最大行号值(C++11 )
4.1 作用
更改预处理器中的当前行号和文件名。
4.2 语法
#line 行号
或者
#line 行号 "文件名"
- 行号必须是至少有一个十进制位的序列,并且始终按十进制解释(即使它以
0开始也是如此)。 - 若行号 为 0 或大于 32767 (C++11 前).则行为未定义,从C++11 起最大改为 2147483647 .
4.3 示例
#include <cassert>
#define FILENAME "line.cpp"
int main(int argc, char *argv[]) {
#line 167 FILENAME
assert( + == );
8 printf("file = %s,line = %d\n",__FILE__,__LINE__);
9 return ;
10}
5.#define 可变参数(C++11)
5.1 语法
#define 标识符( 形参, ... ) 替换列表(可选) (3) (C++11 起)
#define 标识符( ... ) 替换列表(可选) (4) (C++11 起)
- 实参数量必须多于 (C++20 前)形参数量.C++20起改为不少于 .
- 替换列表 可以含有记号序列“
__VA_OPT__ (内容)”,若__VA_ARGS__非空,则它会被 内容 替换,否则不展开成任何内容。
5.2 作用
#define指令的版本 (3) 定义有可变数量实参的仿函数宏。额外的实参可用__VA_ARGS__标识符访问,它会被与要被替换的标识符一起提供的实参替换。#define指令的版本 (4) 定义有可变数量实参的仿函数宏,但无常规实参。额外的实参只能用__VA_ARGS__标识符访问,它会被与要被替换的标识符一起提供的实参替换。
5.3 示例
#include <cstdlib>
#include <cstdio>
#include <cstdarg> void
fun(int count,...){
va_list va; va_start(va,count); for(int i = ; i < count; ++i){
int arg = va_arg(va,int);
printf("arg[%d] = %d , ",i,arg);
} va_end(va);
} #define TYPE int
#define F(...) fun(0 __VA_OPT__(,) __VA_ARGS__)
#define G(X, ...) fun(0, X __VA_OPT__(,) __VA_ARGS__)
#define SDEF(sname, ...) TYPE sname __VA_OPT__([]= { __VA_ARGS__ }) int main(int argc,char *argv[]){
int a = ,b = ,c = ; F(a, b, c); // 替换为 fun(0, a, b, c)
F(); // 替换为 fun(0)
G(a, b, c); // 替换为 fun(0, a, b, c)
G(a, ); // 替换为 fun(0, a)
G(a); // 替换为 fun(0, a)
SDEF(foo); // 替换为 int foo;
SDEF(bar, , ,,); // 替换为 int bar[] = { 1,2,3,4 }; return ;
}
#include <valarray>
#include <cstdio>
#include <cstdlib> int main(int argc,char *argv[]){ #define showlist(...) puts(#__VA_ARGS__) showlist(); // 展开成 puts("")
showlist(, "x", int); // 展开成 puts("1, \"x\", int") return ;
}
#define LOGE(TAG,...) __android_log_print(ANDROID_LOG_ERROR,TAG,__VA_ARGS__) #define LOGW(TAG,...) __android_log_print(ANDROID_LOG_WARN,TAG,__VA_ARGS__) #define LOGD(TAG,...) __android_log_print(ANDROID_LOG_DEBUG,TAG,__VA_ARGS__) #define LOGI(TAG,...) __android_log_print(ANDROID_LOG_INFO,TAG,__VA_ARGS__)
6.新增预定义宏(C++11)
6.1 新增列表
|
__STDC_HOSTED__
|
C++11
|
若实现有宿主(运行在 OS 下)则展开成整数常量 1,不随 OS 运行则展开成 0 |
|
__STDCPP_DEFAULT_NEW_ALIGNMENT__
|
C++17
|
展开成 std::size_t 字面量,其值为对不具对齐的 operator new 的调用所保证的对齐 (较大的对齐将传递给具对齐重载,如 operator new(std::size_t, std::align_val_t)) |
| __STDC_VERSION__ | C++11 | 若存在则为实现定义值 |
| __STDC_ISO_10646__ | C++11 | 若 wchar_t 使用 Unicode ,则展开成 yyyymmL 形式的整数常量,日期指示所支持的 Unicode 的最近版本 |
| __STDC_MB_MIGHT_NEQ_WC__ | C++11 |
若对于基本字符集成员 'x' == L'x' 可能为假,则展开成 1,如在基于 EBCDIC 并且 为 wchar_t 的系统上。 |
| __STDCPP_STRICT_POINTER_SAFETY__ | C++11 | 若实现支持严格的 std::pointer_safety 则展开成 1 |
| __STDCPP_THREADS__ | C++11 | 若程序能拥有多于一个执行线程则展开成 1 |
6.2 示例
#include <cstdio>
#include <cstdlib>
#include <thread> int main(int argc,char *argv[]){ printf("__STDC_HOSTED__ = %s\n",__STDC_HOSTED__ );
printf("__STDCPP_DEFAULT_NEW_ALIGNMENT__ = %s\n",__STDCPP_DEFAULT_NEW_ALIGNMENT__ );
printf("__STDC_VERSION__ = %s\n",__STDC_VERSION__ );
printf("__STDC_ISO_10646__ = %s\n",__STDC_ISO_10646__ );
printf("__STDC_MB_MIGHT_NEQ_WC__ = %s\n",__STDC_MB_MIGHT_NEQ_WC__);
printf("__STDCPP_STRICT_POINTER_SAFETY__ = %s\n",__STDCPP_STRICT_POINTER_SAFETY__);
printf("__STDCPP_THREADS__ = %s\n",__STDCPP_THREADS__); return ;
}
7.__func__(C++11)
7.1 特殊的函数局域预定义变量
C++11 起,在每个函数体的作用域内部,都有一个名为 __func__ 的特殊的函数局域预定义变量,定义为一个持有具有实现定义格式的函数名的静态字符数组。
它不是预处理器宏.
7.2 示例
int main(int argc,char *argv[]){
printf("__DATE__ = %s \n ",__DATE__);
printf("__TIME__ = %s \n ",__TIME__);
printf("__FILE__ = %s \n ",__FILE__);
printf("__LINE__ = %d \n ",__LINE__);
printf("__FUNCTION__ = %s \n ",__FUNCTION__);
printf("__func__ = %s \n ",__func__);
return ;
}
c++新特性实验(1)预处理的更多相关文章
- MySQL8.0新特性实验1
Server层,选项持久化 mysql> show variables like '%max_connections%';+------------------------+-------+| ...
- c++新特性实验(5)声明与定义:属性列表(C++11 起)
1.初识属性 1.1 实验A: noreturn 属性 [[ noreturn ]] static void thread1(void *data){ cout << "nore ...
- c++新特性实验(4)声明与定义:右值引用(C++11)
1.作用 c++11以前,临时对象.字面常量一般情况下不可以再次访问,也不可以修改.右值引用可以解决这个问题. 1.1 实验A #include <iostream> using name ...
- c++新特性实验(2)类型特性
1. 基本类型 1.1 增加 long long long long int signed long long signed long long int unsigned long long unsi ...
- C++11新特性实验
#include <iostream> #include <vector> #include <map> #include <string> #incl ...
- c++新特性实验(3)声明与定义:constexpr
1.作用 constexpr 声明一个函数或变量,它的值可以在编译时出现在常量表达式之中. 2.constexpr 变量要求 其类型必须是 字面类型 (LiteralType) . 它必须被立即初始化 ...
- 01-移动端开发教程-CSS3新特性
1. 移动端开发课程概述 移动互联网的兴起,让移动端的开发迅速蹿红.对于前端开发者来说,移动端的开发已经占据了他们大部分工作时间.接下来老马带大家一起学习移动端开发的相关前端开发技术. 这边课程内容包 ...
- c++学习书籍推荐《深入理解C++11 C++11新特性解析与应用》下载
百度云及其他网盘下载地址:点我 编辑推荐 <深入理解C++11:C++11新特性解析与应用>编辑推荐:C++标准委员会成员和IBM XL编译器中国开发团队共同撰写,权威性毋庸置疑.系统.深 ...
- Java12新特性
switch表达式(预览) 传统switch的缺点 匹配是自上而下的,如果忘记写break, 后面的case语句不论匹配与否都会执行; 所有的case语句共用一个块范围,在不同的case语句定义的变量 ...
随机推荐
- Glassfish安装、基本使用、在idea中配置Glassfish
Glassfish安装.基本使用. 一.glassfish简介 glassfish是一款web应用服务器,和tomcat一样,也是一款优秀的Servlet容器. 二.glassfish知识点 1.do ...
- <每日一题>题目28:简单的python练习题(51-60)
#51.一行代码实现1-100的和 sum(range(1,101)) #52.如何在一个函数内部修改全局变量 ''' 利用global ''' #53.字典如何删除和合并2个字典 ''' del d ...
- RabbitMQ安装到使用入门
一.安装erlang1.sudo vim /etc/yum.repos.d/rabbitmq-erlang.repo,将如下内容复制粘贴进去后保存:[rabbitmq-erlang]name=rabb ...
- putty开源的ssh软件工具
# 登录远程服务器需要ip和端口即可:还是开源工具用起来无忧无虑.无拘无束,这种感觉实在太舒服了,比起xshell开始免费.后来收费好太多太多,不用担心哪天过期了,想干嘛就干嘛. 软件下载地址:htt ...
- Makefile知识点
1.标准Makefile文件示例如下: #把.o .C .cxx .cpp .hxx .h添加到后缀列表中. .SUFFIXES: .o .C .cxx .cpp .hxx .h #设置变量并赋值,方 ...
- JQuery--漂亮的三目运算与jQ选择器结合代码
$(function($) { $("input[name='timeset']").bind('click', function() { $(this).val() == 'cu ...
- iframe加载完成事件
var iframe = document.createElement("iframe"); iframe.src = "http://www.jb51.net" ...
- SQL2005自动备份,定期删除的维护计划及自动定期清除日志
作为一名DBA,他们最常见的日常任务是: 1)定期完成数据库的完全备份或差异备份.2)定期清理备份文件,因为存储空间有限,可能只需要保存一个时期段内的文件(比如一周内或一月内). 而如何做到这两点呢? ...
- 不同目录cookie共享的问题解决 cookie不同页面访问不到的问题
一般设置cookie的方法是setcookie(key, value, expire),参数分别的意思是建.值.过期时间,这里是大众的默认设置方法,但是忽略了一个问题,setcookie还有path与 ...
- PLSQL直接通过客户端连接远程