C++ 11中几个我比较喜欢的语法(二)
之前在文章C++ 11中几个我比较喜欢的语法中介绍了几个我比较喜欢的C++语法,其中有些语法由于VC 11还不支持,无法跨平台,所以没有介绍。前几天VS 2013 Preview发布后,对C++ 11又有了一些支持,因此这里继续完成一下C++ 11语法系列:
原生字符串(raw string literals)
很多时候,当我们只需要一行字符串的时候,字符串转义往往成了一个负担,和写和读都带了很大的不便。例如,对于如下路径"C:\Program Files\Microsoft.NET\ADOMD.NET",我们必须把它写成如下形式:
string path = "C:\\Program Files\\Microsoft.NET\\ADOMD.NET";
可能你会说这个并没有多大影响,下面这个正则表达式的例子呢?你能看出来原文到底是什么吗?
string exp = "('(?:[^\\\\']|\\\\.)*'|\"(?:[^\\\\\"]|\\\\.)*\")|";
在C#中,我们可以通过@关键字来取消字符串转义。现在,在C++ 11中,也增加了这样的语法。对于前面的例子,它的非转义形式为:
string path = R"(C:\Program Files\Microsoft.NET\ADOMD.NET)";
从上面的例子中可以看出,它的语法格式如下:
- 字符串前加'R'前缀
- 字符串首尾加上括号()
它的语法格式比C#的@前缀要稍微复杂点,不过这个复杂也有复杂的好处,那就是字符串里面可以带引号,例如:
string path = R"(this "word" is escaped)";
而C#就无法保持原始字符串格式,对引号仍需要转义:
string path = @"this ""word"" is escaped";
委托构造函数(Delegating constructors)
C++的构造是不能复用的,为了复用其初始化操作,我们往往会增加一个Initial函数:
class Foo
{
private:
int A;
public:
Foo() : A(0)
{
Init();
}
Foo(int
a) : A(a)
{
Init();
}
private:
void Init()
{
// do something
}
};
这样一来就增加了一个只调用一次的Init函数,并且一旦这个Init函数被其它成员函数调用的话,可能导致重复初始化,也是一个隐患。PS:本例比较简单,通过构造函数默认参数也可以解决构造函数复用问题,但默认参数也有一些局限和带来一些问题,限于篇幅就不做更多的讨论了。
在C++ 11中,引入了委托构造函数的语法,其功能和C#中的this构造函数非常类似,就是语法上稍有差异:
class
Foo
{
private:
int A;
public:
Foo() : Foo(0)
{
}
Foo(int
a) : A(a)
{
// do something
}
};
初始化列表(initializer list)
在C++ 03中,可以用列表的形式来初始化数组,这种方式非常直观,但只能适用于数组,不能适用于我们自定义的容器:
int anArray[5] = { 3, 2, 7, 5, 8 }; // ok
std::vector<int> vArray = { 3, 2, 7, 5, 8 }; // not ok
在C++ 11中,我们则可以使得我们自定义的容器对象支持这种列表的形式的初始化方式:
template <typename
T>
class
MyArray
{
private:
vector<T> m_Array;
public:
MyArray() { }
MyArray(const
initializer_list<T>& il)
{
for (auto x : il)
m_Array.push_back(x);
}
};
void main()
{
MyArray<int> foo = { 3, 4, 6, 9 };
}
统一初始化(Uniform initialization)
C++的对象初始化方式是非常多样的:
int a = 2; //"赋值风格"的初始化
int aa [] = { 2, 3 }; //用初始化列表进行的赋值风格的初始化
complex z(1, 2); //"函数风格"的初始化
C++ 11中,允许通过以花括号的形式来调用构造函数。这样多种对象构造方式便可以统一起来了:
int a = { 2 };
int aa [] = { 2, 3 };
complex z = { 1, 2 };
值得一提的是,这种花括号的构造方式还可以用于函数的参数和返回值的类型推导,非常简洁。
void useMyStruct(MyStruct
x)
{
}
useMyStruct({ 2, 3.5f });
MyStruct makeMyStruct(void)
{
return { 2, 3.5f };
}
不过鉴于园子里不少人对C#的var的反感度,估计很多人又要对这种方式高举反对大旗了。
VC对C++ 11的支持情况
由于VS 2013还是Preview阶段,对于c++ 11特性支持还是不全,在今年发布的RTM版本中还会增加 几个特性:

上到了RTM版本后,主要的常用的特性基本上都支持了。剩余的部分,则会在后续的版本中给予支持,如下是VC的RoadMap:http://video.ch9.ms/sessions/build/2013/2-306.pptx,连C++ 14的支持计划也列出来了。总体上感觉MS还是还是比较给力的。
C++ 11中几个我比较喜欢的语法(二)的更多相关文章
- C++ 11中几个我比较喜欢的语法(三)
随着Vsisual Studio 2013 RC版的放出,之前承诺的对C++ 11语法支持已经全部完成,本文是C++ 11中我喜欢的语法系列的最后一部分(一),(二). 非静态成员直接初始化 在C++ ...
- [WPF] 在 Windows 11 中处理 WindowChrome 的圆角
1. Windows 11 的圆角 在直角统治了微软的 UI 设计多年以后,微软突然把直角骂了一顿,说还是圆角好看,于是 Windows 11 随处都可看到圆角设计.Windows 11 使用 3 个 ...
- 从linux0.11中起动部分代码看汇编调用c语言函数
上一篇分析了c语言的函数调用栈情况,知道了c语言的函数调用机制后,我们来看一下,linux0.11中起动部分的代码是如何从汇编跳入c语言函数的.在LINUX 0.11中的head.s文件中会看到如下一 ...
- C++ 11 中的右值引用
C++ 11 中的右值引用 右值引用的功能 首先,我并不介绍什么是右值引用,而是以一个例子里来介绍一下右值引用的功能: #include <iostream> #include &l ...
- IOS中的Block与C++11中的lambda
ios中的block 可以说是一种函数指针,但更确切的讲,其实际上其应该算是object-c对C++11中lambda的支持或者说是一个语言上的变体,其实际内容是一样的,C++的lambda我已经有简 ...
- 在Windows 8.1及IE 11中如何使用HttpWatch
提示:HttpWatch现已更新至v9.1.8,HttpWatch v9.1及以上的版本现都已支持Windows 7,8,8.1和IE 11. 如果你的HttpWatch专业版授权秘钥允许进入vers ...
- C++11中对类(class)新增的特性
C++11中对类(class)新增的特性 default/delete 控制默认函数 在我们没有显式定义类的复制构造函数和赋值操作符的情况下,编译器会为我们生成默认的这两个函数: 默认的赋值函数以内存 ...
- callable object与新增的function相关 C++11中万能的可调用类型声明std::function<...>
在c++11中,一个callable object(可调用对象)可以是函数指针.lambda表达式.重载()的某类对象.bind包裹的某对象等等,有时需要统一管理一些这几类对象,新增的function ...
- [转载] C++11中的右值引用
C++11中的右值引用 May 18, 2015 移动构造函数 C++98中的左值和右值 C++11右值引用和移动语义 强制移动语义std::move() 右值引用和右值的关系 完美转发 引用折叠推导 ...
随机推荐
- complex类的定义、实现
复数类complex的定义.实现(求模.复数加法) #include <iostream> #include <cmath> using namespace std; clas ...
- django 连接MYSQL时,数据迁移时报:django.db.utils.InternalError: (1366, "Incorrect string value: '\\xE9\\x97\\xAE\\xE9\\xA2\\x98' for column 'name' at row 5")
django 连接MYSQL时,数据迁移时报:django.db.utils.InternalError: (1366, "Incorrect string value: '\\xE9\\x ...
- 【Best Time to Buy and Sell Stock III 】cpp
题目: Say you have an array for which the ith element is the price of a given stock on day i. Design a ...
- chrome浏览器设置自动切换代理上网的方法
利用shadowsocks代理软件实现FQ时,如果都走代理模式,流量肯定不够.可以利用chrome的SwitchyOmega插件实现自动根据URL来决定是否使用代理.设置如下: 1.安装Switchy ...
- 几种常见的Android自动化测试框架及其应用
随着Android应用得越来越广,越来越多的公司推出了自己移动应用测试平台.例如,百度的MTC.东软易测云.Testin云测试平台…….由于自己所在项目组就是做终端测试工具的,故抽空了解了下几种常见的 ...
- python-生成器迭代器及递归调用
生成器是一个可迭代的对象,它的执行会记住上一次返回时在函数体中的位置.对生成器第二次(或第 n 次)调用跳转至该函数上次执行位置继续往下执行,而上次调用的所有局部变量都保持不变. 生成器的特点:1.生 ...
- python 学习分享-函数篇
函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数能提高应用的模块性,和代码的重复利用率.你已经知道Python提供了许多内建函数,比如print().但你也可以自己创建函数,这 ...
- [oldboy-django][2深入django]rest-framework教程
# rest-framework教程 - settings.py INSTALL-APPS = [ 'snippets', # app 'rest-framework', ] - 创建model # ...
- Junit单元测试--01
如何编写单元测试 燕双龙 一 单元测试简介 单元测试是代码正确性验证的最重要的工具,也是系统测试当中最重要的环节.也是唯一需要编写代码才能进行测试的一种测试方法.在标准的开发过程中,单元测试的代码与实 ...
- BZOJ 1015:[JSOI2008]星球大战starwar(逆向处理+并查集)
[JSOI2008]星球大战starwar 时间限制: 3 Sec 内存限制: 162 MB[题目描述] ...