您当前的位置: 首页 >  c++

phymat.nico

暂无认证

  • 2浏览

    0关注

    1967博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

关于C++14:你需要知道的新特性

phymat.nico 发布时间:2018-01-24 00:27:25 ,浏览量:2

使C++更加安全和更加方便的有用新特性

今年8月,经过投票, C++14标准获得一致通过。目前唯一剩下的工作是ISO进行C++标准的正式发布。在本文中,我关注的是新标准中的几个重要点,展示了即将到来的改变会如何影响你的编程方式,特别是在使用被现代C++称之为习语和范型的特性时。

C++标准委员会决心使标准制定过程比过去10年更加快速。这意味着,距上一个标准(即C++11)仅3年的C++14是一次相对较小的发布。这远非一个令人失望的消息,恰恰相反,这对程序员来说是个好消息。因为这样的话,开发人员能够实时地跟上新特性。所以,今天你就可以开始使用C++14的新特性了—而且,如果你的工具链足够灵活的话,你几乎可以使用全部新特性了。

目前你可以从这里得到标准草案的一份免费副本。遗憾的是,当最终版本的标准发布时,ISO会进行收费。

缩短标准发布的时间间隔可以帮助编译器作者更实时地跟上语言变化。仅隔三年就再次发布,需要调整以适应的变化也就更少。

本文的例子主要在clang 3.4上测试过,clang 3.4覆盖了大多数C++14的新特性。目前,g++对新特性的覆盖更少一些,而Visual C++似乎落后更多。

C++14:重大变化

接下来,本文将说明对程序员编码工作会有重大影响的C++14特性,在给出实例的同时,还讨论了何时何地因何使用这些特性。

返回类型推导

在这次发布中,关键字auto的作用扩大了。C++语言本身仍然是类型安全的,但是类型安全的机制逐渐改由编译器而不是程序员来实现。

在C++11中,程序员最初使用auto是用于声明。这对于像迭代器的创建之类尤其有用,因为完整的正确的类型名可能长得可怕。使用了auto的C++代码则易读得多:

1
for ( auto ii = collection.begin() ; ...

在C++14中,auto的使用在好几个方面得到了扩展。其中之一便是意义非凡的返回类型推导。在一个函数中编写如下一行代码:这段代码依然完全地是类型安全的,因为编译器知道begin()在上下文中应该返回什么类型。因此,ii的类型是毫无疑问的,并且在使用ii的每个地方,编译器都会进行检查。

1
return 1.4;

对于程序员和编译器来说,很显然,函数返回的是double类型。因此在C++14中,程序员可以用auto代替double来定义函数返回类型:

1
auto getvalue() {

这个新特性需要注意的一个细节也是相当容易理解的。那就是,如果一个函数有多个返回路径,那么每个返回路径返回的值需要具有相同的类型。

1
2
3
4
5
6
7
auto f( int i)
{
   if ( i < 0 )
     return -1;
   else
     return 2.0
}

上面这段代码似乎显然应该推导出返回类型是double,但是C++14禁止这种带歧义性的使用。对于上述代码,编译器会报错:

1
2
3
4
5
error_01.cpp:6:5: error: 'auto' in return type deduced as 'double' here but deduced as 'int' in
       earlier return statement
     return 2.0
     ^
1 error generated.

为C++程序增加推导返回类型这一特性有诸多很好的理由。第一个理由是,有时候需要返回相当复杂的类型,例如,在STL容器中进行搜索时可能需要返回迭代器类型。auto使函数更易编写,更具可读性。第二个(可能不那么明显的)理由是,auto的使用能够增强你的重构能力。考虑以下程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include
#include
#include
 
struct record {
    std::string name;
    int id;
};
 
auto find_id( const std::vector &people,
              const std::string &name)
{
   auto match_name = [&name]( const record& r) -> bool {
     return r.name == name;
   };
   auto ii = find_if(people.begin(), people.end(), match_name );
   if (ii == people.end())
     return -1;
   else
     return ii->id;
}
 
int main()
{
   std::vector roster = { { "mark" ,1},
                                  { "bill" ,2},
                                  { "ted" ,3}};
   std::cout
关注
打赏
1659628745
查看更多评论
0.3687s