之前在文章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)";

从上面的例子中可以看出,它的语法格式如下:

  1. 字符串前加'R'前缀
  2. 字符串首尾加上括号()

它的语法格式比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中几个我比较喜欢的语法(二)的更多相关文章

  1. C++ 11中几个我比较喜欢的语法(三)

    随着Vsisual Studio 2013 RC版的放出,之前承诺的对C++ 11语法支持已经全部完成,本文是C++ 11中我喜欢的语法系列的最后一部分(一),(二). 非静态成员直接初始化 在C++ ...

  2. [WPF] 在 Windows 11 中处理 WindowChrome 的圆角

    1. Windows 11 的圆角 在直角统治了微软的 UI 设计多年以后,微软突然把直角骂了一顿,说还是圆角好看,于是 Windows 11 随处都可看到圆角设计.Windows 11 使用 3 个 ...

  3. 从linux0.11中起动部分代码看汇编调用c语言函数

    上一篇分析了c语言的函数调用栈情况,知道了c语言的函数调用机制后,我们来看一下,linux0.11中起动部分的代码是如何从汇编跳入c语言函数的.在LINUX 0.11中的head.s文件中会看到如下一 ...

  4. C++ 11 中的右值引用

    C++ 11 中的右值引用 右值引用的功能 首先,我并不介绍什么是右值引用,而是以一个例子里来介绍一下右值引用的功能: #include <iostream>    #include &l ...

  5. IOS中的Block与C++11中的lambda

    ios中的block 可以说是一种函数指针,但更确切的讲,其实际上其应该算是object-c对C++11中lambda的支持或者说是一个语言上的变体,其实际内容是一样的,C++的lambda我已经有简 ...

  6. 在Windows 8.1及IE 11中如何使用HttpWatch

    提示:HttpWatch现已更新至v9.1.8,HttpWatch v9.1及以上的版本现都已支持Windows 7,8,8.1和IE 11. 如果你的HttpWatch专业版授权秘钥允许进入vers ...

  7. C++11中对类(class)新增的特性

    C++11中对类(class)新增的特性 default/delete 控制默认函数 在我们没有显式定义类的复制构造函数和赋值操作符的情况下,编译器会为我们生成默认的这两个函数: 默认的赋值函数以内存 ...

  8. callable object与新增的function相关 C++11中万能的可调用类型声明std::function<...>

    在c++11中,一个callable object(可调用对象)可以是函数指针.lambda表达式.重载()的某类对象.bind包裹的某对象等等,有时需要统一管理一些这几类对象,新增的function ...

  9. [转载] C++11中的右值引用

    C++11中的右值引用 May 18, 2015 移动构造函数 C++98中的左值和右值 C++11右值引用和移动语义 强制移动语义std::move() 右值引用和右值的关系 完美转发 引用折叠推导 ...

随机推荐

  1. 回顾Scrum学习:《Scrum实战》第4次课【全职的Scrum Master】作业

    回顾Scrum学习   1.回顾目标 1.1 期望结果 了解和学习Scrum,为将来换方向打好理论基础 如果能在目前公司引入和推行也很好,但是根据目前公司的文化氛围来看,推行希望不大 把敏捷思想应用到 ...

  2. 创建 PSO

    TechNet 库 Windows Server Windows Server 2008 R2 und Windows Server 2008 浏览 Windows Server 技术 Active ...

  3. cookie注意事项

    cookie是在 HTTP 协议下,服务器或脚本可以维护客户工作站上信息的一种方式. 四种会话跟踪技术(URL重写.隐藏表单域.Cookie.Session) 服务端技术:URL重写,Session, ...

  4. 对CRC32的小结加上bugku一道题目:好多压缩包

    CRC32就是校验值,一般来说不同的文件校验值不一样,所以我们可以挨个爆破,当然这是在文件比较小的时候.下面是几种情形. 1. 我新建了一个flag.txt文档,里面是我的生日20180818 然后我 ...

  5. jeakins+maven+jmeter构建性能测试自动化( 在eclipse里运行如果出现没有找到“*.loadtest.xls”,请将此文件名修改为你对应使用的xsl文件名)

    背景: 首先用jmeter录制或者书写性能测试的脚本,用maven添加相关依赖,把性能测试的代码提交到github,在jenkins配置git下载性能测试的代码,配置运行脚本和测试报告,配置运行失败自 ...

  6. python 笔试总结

    1.对比两种函数对应结果 def fn(x): if x>0: print(x) fn(x-1) ****结果****** 3 2 1 $$$$$$另外一种$$$$$$$$$ def fn(x) ...

  7. [oldboy-django][2深入django]Form总结

    1 form总结 # Form数据格式验证 - 原理: - 流程 a.写类LoginForm(Form): 字段名 = fields.xxFields() # 验证规则,本质是正则表达式(fields ...

  8. [oldboy-django][5python基础][内置方法]dir 如何查看一个对象有哪些方法

    f = open('/etc/password', 'r') print(dir(f))

  9. 快速排序(Quick Sort)及优化

    原理介绍 通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成 ...

  10. Spring 简单而强大的事务管理功能

    开始之前 关于本教程 本教程将深入讲解 Spring 简单而强大的事务管理功能,包括编程式事务和声明式事务.通过对本教程的学习,您将能够理解 Spring 事务管理的本质,并灵活运用之. 先决条件 本 ...