C++11的部分新特性解析

C++11的部分新特性解析

1. 声明参数的简写形式
int i = 0;可写为int i(0);
string s = “123”;可写为 string s{“123”};
int a[3] = {1,2,3};可写为int a[3]{1,2,3};


2. For循环的简写形式
例:
输出int list[10]中的每个元素。
原写法

for (int i(0); i < 10; i++)
    cout << list[i] << endl;

新写法

for (int i : list)
    cout << i << endl;

两种写法完全等价。


3. 自动类型
声明变量的时候,如果是声明+赋值的形式,则可以将类型一律声明为auto,而无须指定具体的类型。
例:

auto a = 1;
auto b = 1.6;

此处a的类型由后面1的类型决定,为int。
而decltype可以理解为auto的反函数,获取类型。
例:
用a的类型声明b。

auto a = 1;
decltype(a) b;

4. Tuple(元组)
Tuple可以理解为,将任意个数的完全不同的类型的变量放在同一个数组中。
可以类比python中的tuple,基本一致。可以参考我的另一篇文章 C++中使用tuple 。只将重点列出来。
例:
生成tuple

auto tup1 = std::make_tuple("Hello World!", 'a', 3.14, 0);

上述代码创建了一个tuple <const char*, char, double, int>类型的元组。
拆开tuple

auto tup1 = std::make_tuple(3.14, 1, 'a');
double a;
int b;
char c;
std::tie(a, b, c) = tup1;

这样做的结果是a = 3.14, b = 1, c = 'a'
如果不想要某一位的值,可以直接将其用ignore代替。

std::tie(ignore, b, c) = tup1;

连接tuple

std::tuple<float, string> tup1(3.14, "pi");
std::tuple<int, char> tup2(10, 'a');
auto tup3 = tuple_cat(tup1, tup2);

输出第i个元素

std::tuple<float, string> tup1(3.14, "pi");
cout << get<i>(tup1);

5. Lambda语法
Lambda语法可类比python,在我的另一篇文章中有详细描述,C++中使用Lambda,可参考。只将重点列出来。
Lambda用于快速声明匿名的函数。格式如下:
lambda
1. 传递方式可以为空,&,=,或者为每一个外部参数指明传递方式。= 表示为值传递方式,& 表示为引用传递方式。就算为空,中括号也不可以省略。
2. 参数列表即函数的参数,参数可以按值或者按引用传递。如果没有参数,可以省略(包括小括号)。
3. mutable是可选的,如果声明了mutable则可以修改按值传递进来的参数的拷贝(在lambda表达式外修改不可见)。
4. throw也是可选的,用来抛出函数处理过程中的异常,需制定抛出的异常的类型。
5. 返回类型是函数返回值的类型,在两种情况下可以省略,在后面叙述。
6. 函数体,实现功能的部分。

例:

int add(int x, int y)
{
    return x + y;
}

与下面的lambda表达式等价

auto add = [](int x, int y) -> int { return x + y; };

区别是第二种声明方式可以声明在函数内部。C++是不允许函数嵌套的。

当然lambda并不是只能用来这样声明函数(这样声明反而更繁琐),而是用来配合一些新的语法使用。


6. 可配合Lambda的语法
for_each,可以类比python中的map,即对与数组中的每一个元素都执行定义的方法。
例1:
将一个10个元素的int数组,int list[10]中每个元素乘以2。

for_each(list, list + 10, [=](int &i) {i = i * 2; });

可以看出for_each是由3个参数组成的,第一个参数为指向数组起始位置的指针,第二个参数为指向数组末尾的指针,第三个参数就是使用lambda定义的函数。执行的时候,实际上是对于数组中的每一个元素都执行这一个函数。其中的输入参数i在实际执行时就是数组中的一个元素。
如果list是vector、list等具有迭代器的stl模板,则写法为

for_each(list.begin(), list.end(), [=](int &i) {i = i * 2; });

例2:
将一个10个元素的int数组,int list[10]赋值为1~10;

for_each(list, list + 10, [=](int &i) {i = &i - list + 1; });

find_if,用于查找指定条件的元素(返回指向第一个满足条件的元素的指针或迭代器)
例:
查找第一个偶数的位置

vector<int> a = { 1, 2, 3, 4 };
auto res = find_if(a.begin(), a.end(), [](int x) -> bool { return x % 2 == 0; });

find_if也是三个元素,对比参照for_each理解即可。

count_if,用于统计满足指定条件的元素的个数
例:
统计偶数个数

vector<int> a = { 1, 2, 3, 4 };
auto res = count_if(a.begin(), a.end(), [](int x) -> bool { return x % 2 == 0; });

参数与find_if完全一致。

copy_if,提取满足条件的所有元素
例:
提取a中所有偶数并复制到b中

vector<int> a = { 1, 2, 3, 4 };
vector<int> b(a.size());
auto res = copy_if(a.begin(), a.end(), b.begin(), [](int x) -> bool { return x % 2 == 0; });
b.resize(distance(b.begin(), res));

参数与find_if完全一致。

关于find_if,copy_if和count_if的更详细用法,可以关注我的另一篇文章[C++快速开发] 查询


7. 空指针nullptr
在c++11以前一般空指针用NULL,而NULL的定义是0。
在c++11以后,尽量用nullptr,而不要用NULL。nullptr就是一个特殊的类型,代表空指针,他不等于0,也不是int类型。
这是一个编程习惯的问题,并不是强制性要求。
因为这样可以解决一个可能的歧义问题。因为函数可以重载,所以可以这样声明。

void F(int a) 
{
    cout << a << endl;
}
void F(int *p) 
{
    cout << *p << endl;
}

如果按照以前的定义方式,声明一个空指针,int *p = NULL,那么调用F函数F(p)时会因为歧义而导致崩溃,因为NULL的定义就是0是int类型,那么参数该怎样被解释?是int还是int*?在某些编译器中执行时会有bug。如果改为使用nullptr则可以避免该问题。


8. 关键字final和override
override用于修饰虚函数,用override修饰的虚函数必须在派生类中进行重载,否则会报错。避免了以前可能错误使用未重载的虚函数而导致错误。
final与override作用完全相反,防止虚函数被重写。


9. 多线程
多线程可以参考我的另一篇文章 C++多线程 。下面只列出重点。
例:
创建线程并输出一句话

thread t([] {cout << "new thread!" << endl; });
t.join();

配合mutex可以执行锁操作。
例:
双线程对同一变量执行加一操作

mutex m;
int count = 0;
auto increase = [&]  //定义增加函数
{
    m.lock();  //用于互斥访问的锁
    count++;
    cout << "id: " << this_thread::get_id() << endl;
    m.unlock();
    this_thread::sleep_for(chrono::milliseconds(100));
};
thread t1([increase]
{
    for (int i = 0; i < 5; i++)
        increase();
});
thread t2([increase]
{
    for (int i = 0; i < 5; i++)
        increase();
});
t1.join();
t2.join();

10. function与bind
function适用于解决以前函数指针的不安全问题。用于将一个可调用实体进行包裹,实现泛型函数的回调。
理解的时候,就把它当作函数指针的安全替代品。
例:

//函数
int Test(int a)
{
    return a;
}

//仿函数
class Test2
{
public:
    int operator()(int a)
    {
        return a;
    }
};

//lambda
auto Test3 = [](int a){ return a; };

//类成员函数
class TestClass
{
public:
    int Test(int a) { return a; }
};

std::function< int(int)> F;

int main()
{
    F = Test;
    F(10);
    Test2 T;
    F = T;
    F(10);
    F = Test3;
    F(10);
    TestClass TClass;
    std::function< int(int)> TFunc = std::bind(&TestClass::Test, TClass, std::placeholders::_1);
}

通过上面的例子,可以看出,其中所指的可调用实体可以为普通函数、lambda泛型函数、仿函数、类成员函数等。解释下bind,实际上是一种将类的成员函数绑定到类对象和参数的方法。placeholders是表示不绑定对象,后面的数字表示对象的位置。再给一个简单的例子,绑定普通函数。

int Test(int x, int y);
auto func = std::bind(Test, 10, std::placeholders::_1);
func(20);

执行func(20)实际上相当于执行了Test(10,20);


11. 右值引用
右值引用以&&表示。可以优化代码,减少时间。
可参考我的另一篇文章C++右值引用 。不再多余叙述。


使用C++11的新语法,做的回溯生成数独的算法,可参考 [C++] 回溯法生成数独


代码通过Visual Studio 2015测试。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 《深入理解C11特性解析与应用》是一本介绍C11特性的书籍,该书主要从理论和实践两个方面对C11中的特性进行了详细解析和应用。 首先,在理论方面,该书从语言层面介绍了C11中的特性,如泛型选择和宏扩展、多线程编程、原子操作、内存模型和并发性等。通过深入分析这些特性的设计思想和应用场景,读者可以更好地理解C11的语言特性和底层实现机制。 其次,在实践方面,该书通过实例和案例分析来演示C11特性的具体应用。例如,通过使用泛型选择和宏扩展,读者可以编写更加通用和高效的代码,提高代码的可读性和维护性。同时,通过学习多线程编程和原子操作,读者可以利用多核处理器和并行计算资源,更好地提升程序的性能和并发性。此外,该书还介绍了C11中对内存模型和并发性的支持,帮助读者编写更加健壮和可靠的多线程程序。 总之,《深入理解C11特性解析与应用》通过理论和实践相结合的方式,全面而深入地介绍了C11中的特性,并通过实例和案例演示了它们的具体应用。这本书对于想要深入了解C11特性的开发者来说是一本很有价值的参考资料,可以帮助他们更好地理解和应用C11的特性,提高代码的质量和效率。 ### 回答2: 《深入理解C 11_特性解析与应用》是一本介绍C语言特性的书籍,它对C语言中增的特性进行了详细解析,并提供了实际应用示例。 C语言是一种广泛应用于系统编程和底层开发的编程语言,它的更版本C11引入了一些特性,使得C语言更加现代化和强大。 这本书的第一部分从C语言的历史和发展背景入手,介绍了C11的重要性和应用场景。然后,它详细讲解了C11中增的特性,如更灵活的数组初始化、多线程编程支持、原子操作等。通过深入讲解这些特性,读者可以更好地理解它们的原理和用法。 在第二部分中,这本书提供了一系列的示例代码,帮助读者更好地应用C11中的特性。这些示例涵盖了各种应用场景,例如并行编程、网络编程和数据结构等。读者可以通过实际操作这些示例代码,加深对C11特性的理解和应用能力。 此外,这本书还提供了一些实践建议,帮助读者在使用C11特性时避免一些常见的问题和陷阱。通过学习这些建议,读者可以写出更高效、更安全的C代码。 总之,《深入理解C 11_特性解析与应用》是一本帮助读者深入理解C11特性并应用于实际开发的重要参考书籍。通过学习这本书,读者可以更好地掌握C语言的特性,提高程序开发的效率和质量。 ### 回答3: 《深入理解C 11_特性解析与应用》是一本介绍C语言特性的书籍,通过对C语言11版本的特性进行解析和应用的方式,帮助读者更深入地理解C语言的特性和用法。 本书首先介绍了C语言11版本的特性,如增的数据类型、语法糖和函数特性等。接着,通过实际的例子和应用场景,详细解释了这些特性的用法和作用。读者可以通过实际的代码演示和分析,更好地理解和掌握这些特性。 此外,本书还对C语言11版本的特性进行了深入的分析和讲解。通过解读语言规范和源码实现,揭示了C语言11版本背后的设计思想和实现原理。这种深入的理解有助于读者更好地掌握这些特性,并能够灵活地应用到实际的项目中。 《深入理解C 11_特性解析与应用》对需要深入理解C语言特性的读者来说是一本很有价值的书籍。通过对C语言11版本的特性进行解析和应用的方式,读者可以更深入地了解C语言的特性和用法,提升自己在C语言开发中的技能和水平。无论是初学者还是有一定经验的开发者,都可以从中受益匪浅。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值