开源中国

我们不支持 IE 10 及以下版本浏览器

It appears you’re using an unsupported browser

为了获得更好的浏览体验,我们强烈建议您使用较新版本的 Chrome、 Firefox、 Safari 等,或者升级到最新版本的IE浏览器。 如果您使用的是 IE 11 或以上版本,请关闭“兼容性视图”。
C++17 将有什么变革? - 技术翻译 - 开源中国社区

C++17 将有什么变革? 【已翻译100%】

标签: <无>
oschina 推荐于 3年前 (共 12 段, 翻译完成于 11-25) 评论 73
收藏  
58
推荐标签: 待读

这是我对当前在厄巴纳举行的C++委员会会议上的提案方面文章的第三部分。 这次是全部关于子组变革的,对这方面,我写了很多文章,所以这仅仅是第一部分。 前面那些部分是关于并发(concurrency)的, 然后 第二部分是关于核心,网络,模型以及未定义行为方面的

变革

N4126 - 显式默认比较操作符

这个提议已经在上一部分的反射部分提到了,在那里我们用反射和std::tie解决这个问题。这份提议想让 = default变得合法; 对于所有的操作符 (>,<,==,!=, ...)。这些操作符仍然使用友元方法来实现,如下例所示:

class Thing
{
    int a, b;
public:
    // ...
    friend bool operator<(const Thing&, const Thing&) = default;
    friend bool operator>(const Thing&, const Thing&) = default;
    friend bool operator<=(const Thing&, const Thing&) = default;
    friend bool operator>=(const Thing&, const Thing&) = default;
};

junker
 翻译得不错哦!

N4127 - 检查后的解引用条件

因为已经提议过有范围的for(ranged-for)循环,这个提议转移到auto和默认类型.如果没有提供类型,它也希望,在其它语句中,引进或采用有范围的for的语法,使之合法,例如if语句:

std::weak_ptr<foo> wp;
if(x: wp.lock())

对于C++来说,这是一个巨大的改变,并且不是每个人都喜欢它,特别地,编译器的创建者不得不处理这所波及的范围.然而,如果委员会认可了下个版本的有范围的for循环,那么在其他C++控制结构,如if,while,for等,中允许同样的语法也就说得通了.

gones945
 翻译得不错哦!

N4131 - 显式的绝不应该是隐式的

这篇文章对应的是N4074,它争论提议的变化内容,即让{expr}显式的返回是错误的,因为显式的决不应该是隐式的.关于草案中的更多细节,作者甚至给出了一个例子,说N4074提案可能导致未定义的行为.

N4135 -运行时按规定校验的语言支持 (修订8)

作者提供了很好的概述:

如果足够仔细,我们可以创建本质上无缺陷的库.但是即便是最好的库,只要使用不当,都可能产生灾难性的的后果.运行时按规定校验的实际应用:当函数调用时,检测前缀条件的过程,有助于在早期测试中,发现误用的情况.同时也有助于提升开发速度,增强软件健壮性.将按规定校验拓展为开发阶段而不仅仅是早期测试阶段,将带来更多长远的益处.

gones945
 翻译得不错哦!

N4147 - 内联变量,或封装表达式

作者再一次提供了很好的概述:

内联函数为对外无法暴露对象的接口,提供了合适的行为.尽管是不自然的样版,通常还是会鼓励用户使用它们来包装全局变量.其它的变通方法包括类的静态数据成员,枚举,宏和变量模板,所有这些都有奇怪的语法或缺陷,限制了适用性.这个提议在变量定义上面指定了inline标识符,这意味着在语义上类似于内联函数的评估和链接.更通用的,这为命名值或非持续性变量提供了一种工具,它可以替代或补充 各种各样的变通方法.

N4148 - 不允许来自易拷贝类型的不可访问操作符

当前对于易拷贝类型(trivially copyable type)的定义有一个缺陷:它对于不可访问的/删除的 拷贝/移动 构造函数和赋值操作符同样有效.一个易拷贝对象也可以通过使用std::memcpy来拷贝,特别是当有一个易拷贝对象数组的时候,这在性能上更优.然而,对于一个删除的/不可访问的 拷贝/移动 构造函数或者赋值操作符,这样做是不明智的.作者提议更新标准里面的措辞,并提高特性,让std::is_trivially_copyable针对不可访问的/删除的 拷贝/移动 构造函数和操作符返回错误.

gones945
 翻译得不错哦!

N4149 - 明确且合适的类

同样的,这篇文章也有很好的概述:

一些类只在某些上下文中工作: 作用域守护(scope guard)作为子表达式通常是没有用处的,表达式模板占位符作为局部变量也会出现问题.一个没有使用的函数的结果可能意味着调用者会使用不同的协议,如std::async.这个提议拓展了类的声明来阻止这类错误,并增加了通过类型替换自动解决它们的技术,例如一个表达式模板的值类型.另外,不可移动的对象的生成变得更加容易处理.

增加的功能包括"自动评估"提议里面提到的.这个提议更具表现力,可以更广泛的应用,并且易于接受和使用.

gones945
 翻译得不错哦!

N4150 - 别名集合属性: 针对C++中restrict一样的别名语义

这个提议想增加restrict修饰符到C++,因为它已经存在于C99之中,同时,一些编译器已经提供了restrict作为一个C++拓展。由于目前没有定义restrict修饰符,作者寻求定义如何正确的使用它,特别是在C++ 11中像lambda一样的特性。

N4152 - 未捕获的异常

这篇文章想提高std::uncaught_exception的可用性:

函数 int std::uncaught_exceptions() 返回了异常对象的数目,这些对象已经初始化,并被抛出或者被重新抛出,但是没有激活任何处理程序.

gones945
 翻译得不错哦!

N4154 - 操作符断言

这个提议想让assert(断言)成为语言结构,而不是一个宏定义:

assert宏定义从未表现得像一个真正的函数,在可以预见的未来,它将更像是一个操作符.在C中宏定义的表现方式,阻止了生产模式下的优化,但是在调试模式下却允许产生任意的副作用.增加assert作为一个关键字和内置的操作符将产生益处,而不会存在任何副作用.

N4160 - 值约束

这篇文章分析了如何在C++中支持契约式编程(contract programming)风格的特性.它尝试着提供一个概况,关于如何在编译时而不是运行时检查的时候支持契约.作者定义了文档的范围,如下:

鉴于[N1962] 是一篇关于在C++之中增加契约式编程支持的相当完整的提议,这个文档提供的是问题范围,而不是一个特定的提议.我们集中于确认期望值,潜在的实现困难以及代价.

我们知道的其它契约式编程提议 — [N4075], [N4110] — 建立在一个假设之上.即前置条件的支持,必须以提供某种形式之下:在函数调用之前评估前置条件,偶尔取消前置条件的评估以及安装未履行契约的处理程序.在这篇文章中,我们不会想当然的做这种假设.运行时支持只是我们分析范围的一个子集.我们更细致的探索了一个可选方案:集中于静态分析.

gones945
 翻译得不错哦!

N4164 - 前向引用

作为正式的通用引用, 类型T&& 总是右值(r-value)引用,除了作为模板参数或者使用了auto关键字。技术上仍然是右值引用,但是在这种情况下,表现上是非常不同。到目前为止,标准不识别这点,作者想介绍这个术语前向引用(forwarding reference),关于在模板和auto关键字之中的右值引用。

N4165 - 统一调用语法

成员函数的调用语法是x.f() 或者 x->f(),而非成员函数则是f(x).这在泛型编程代码中会是一个问题,因为没有统一的调用语法,而泛型编程代码必须决定是调用成员函数还是非成员函数。

为了解决这个问题,作者提议允许使用语法x./->f()来调用自由函数,如果函数的第一个参数是x的指针或者引用。这也很好的满足C的用法,当函数第一个指针参数是一个结构体的时候。作者使用FILE*和fseek作为例子。

gones945
 翻译得不错哦!

N4166 - 可移动的初始化列表

当前,std::initializer_list不是可移动的,它是在移动语义变得重要之前设计的.同时,那个时候只提供拷贝语义看起来是足够的,但是今天的情况已经发生了变化.作者提议一个模板化版本的std::intializer_list,它继承于非右值intializer_list类型:

template< typename T >
struct initializer_list< T && >
  : initializer_list< T > {

这个构造实现了所有权和移动语义.

gones945
 翻译得不错哦!

N4172 - 命名参数

命名参数的语法看起来和提议中的 "有范围的for(ranged-for)循环" 类似。但是在近似(几乎一样)的语法表达下面,两者有不同的意义。在一个函数调用过程中,你可以像下面例子中这样对命名参数赋值:

void foo(int x, int y, int z);
foo(40,z: 30, y:20);

在这个例子里面的函数调用过程中,参数z的值是30, 参数x的值是40。另外,非命名参数不能放在命名参数之后。

nzchris
 翻译得不错哦!
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们
评论(73)
Ctrl/CMD+Enter

C11都没用到多少特性! 都c17了!这版本帝拼的
linux说不关我的事
特性太多,用的少,还复杂
C++早点死了吧,有C足矣
其实我觉得多一些语法糖 还是挺好的.
用起来简便...

请多给C++加一些.
auto arr[] = {1..20}; //1, 2, 3, ... 20
比 用 generate 舒服多了吧, 哈哈哈哈...
跟不上趟了~~
拜托,这么多新特性gcc完成得了么?

引用来自“uudiin”的评论

C++早点死了吧,有C足矣
你觉得这样的回复会显得你很有逼格么?

引用来自“莫太闲”的评论

拜托,这么多新特性gcc完成得了么?
的确, 对编译器来说, 压力N大.
C++越来越丧心病狂了,是不是要做所有语言的超集,这里增加边好多object-c特性哦
写java的表示毫无压力
感觉有点抄袭objective-c
都17了啊
一直没用过C++ 也没关注过
C++11还没怎么用呢,这又是14又是17的,咳。动态语言的特性,就留给动态语言去用才好。
gcc不会有压力,gcc牛人太多。
大部分新特性 都是为了fix老的语法弊端和性能。。越是复杂的语法。。使用过程中越是容易出bug和性能问题。。c++正在走向一条不归路。。回归c的本质吧。。否则迟早没落。。
17了?
模板和异常方面一点都没变化?它们才是最需要改的吧?
估计到C艹20的时候,编译一个Hello World都要20分钟了

引用来自“航海家”的评论

gcc不会有压力,gcc牛人太多。
还在用gcc ,用clang吧
顶部