C++16能设计什么图案一个图案使其能按照wsad上下左右移动一格

05 C++课程设计_迷你高尔夫_图文_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
05 C++课程设计_迷你高尔夫
阅读已结束,下载文档到电脑
想免费下载更多文档?
定制HR最喜欢的简历
下载文档到电脑,方便使用
还剩12页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢正在收集C++专题的练手项目,下面几个质量不错推荐下,实验楼有配套的练习环境。&br&&br&8月22日更新:&br&&a href=&///?target=https%3A///courses/569& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&C/C++ - C++ 打造 Markdown 解析器&i class=&icon-external&&&/i&&/a&&br&Markdown 几乎成为了程序员编写文档的标配,解析 Markdown 文本能够加深日后编写编译器中词法分析的理解,本项目使用 C++ 实现 Markdown 解析器,并将解析的内容生成为 HTML。&br&&img src=&/a8d74b6f9bff0bf0ec4c_b.png& data-rawwidth=&496& data-rawheight=&270& class=&origin_image zh-lightbox-thumb& width=&496& data-original=&/a8d74b6f9bff0bf0ec4c_r.png&&&br&&br&&b&1.&a class=& wrap external& href=&///?target=https%3A///courses/558& target=&_blank& rel=&nofollow noreferrer&&C/C++ - C++ 实现太阳系行星系统&i class=&icon-external&&&/i&&/a&&/b&&br&使用 C++实现 OpenGL GLUT 实现一个简单的太阳系行星系统,将涉及一些三维图形技术的数学基础、OpenGL 里的三维坐标系、OpenGL 里的光照模型、GLUT 的键盘事件处理。&br&&b&&img data-rawheight=&402& data-rawwidth=&500& src=&/652bb53bef5fca8_b.png& class=&origin_image zh-lightbox-thumb& width=&500& data-original=&/652bb53bef5fca8_r.png&&2.&a class=& wrap external& href=&///?target=https%3A///courses/560& target=&_blank& rel=&nofollow noreferrer&&C/C++ - C++实现运动目标的追踪&i class=&icon-external&&&/i&&/a&&/b&&br&本次实验将使用利用 OpenCV 来实现对视频中动态物体的追踪。&b&&br&3.&/b&&b&&a class=& wrap external& href=&///?target=https%3A///courses/557& target=&_blank& rel=&nofollow noreferrer&&C/C++ - C++ 实现银行排队服务模拟&i class=&icon-external&&&/i&&/a&&/b&&br&使用 C++对银行排队服务进行模拟,以事件驱动为核心思想,手动实现模板链式队列、随机数产生器等内容,进而学习概率编程等知识。作为可选进阶,这个模型同时还能稍加修改的应用到 CPU 资源争夺模型中。
&br&&b&4.&/b&&b&&a class=& wrap external& href=&///?target=https%3A///courses/545& target=&_blank& rel=&nofollow noreferrer&&C/C++ - 1小时入门增强现实技术&i class=&icon-external&&&/i&&/a&&/b&&br&仅需C++语言基础,本课程将基于OpenCV实现一个将3D模型显示在现实中的小例子,学习基于Marker的AR技术,既简单又有趣。&br&&img data-rawheight=&328& data-rawwidth=&500& src=&/e718d75ed5ee05c69533_b.png& class=&origin_image zh-lightbox-thumb& width=&500& data-original=&/e718d75ed5ee05c69533_r.png&&&b&5.&a class=& wrap external& href=&///?target=https%3A///courses/565& target=&_blank& rel=&nofollow noreferrer&&C/C++ - 100 行 C++ 代码实现线程池&i class=&icon-external&&&/i&&/a&&/b&&br&为了追求性能,在服务器开发中我们经常要面临大量线程任务之间的调度和管理,本次实验我们将使用 C++ 及大量 C++11新特性设计并实现一个线程池库。 &br&&b&6.&a class=& wrap external& href=&///?target=https%3A///courses/559& target=&_blank& rel=&nofollow noreferrer&&C/C++ - C++实现第一人称射击游戏&i class=&icon-external&&&/i&&/a&&/b&&br&使用 OpenGL 实现一个第一人称射击类游戏,涉及键盘鼠标的处理、三维视角变换处理、素材加载渲染等。 &br&&img src=&/46c18dc4e1feeee_b.png& data-rawwidth=&500& data-rawheight=&421& class=&origin_image zh-lightbox-thumb& width=&500& data-original=&/46c18dc4e1feeee_r.png&&&b&7.&a href=&///?target=https%3A///courses/566& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&C/C++ - C++ 实现高性能内存池&i class=&icon-external&&&/i&&/a&&/b&&br&获得内存池所分配的内存速度高于从堆中获得分配的内存的速度。和标准库中的默认分配器一样,内存池本质上也是分配器,本次实验将设计并使用 C++实现一个高性能内存池。&br&&br&本答案会继续增加新项目,如果你有好项目也欢迎投稿来做成项目课分享给大家:&br&&a class=& external& href=&///?target=https%3A///contribute& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://www.&/span&&span class=&visible&&/contribut&/span&&span class=&invisible&&e&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&
正在收集C++专题的练手项目,下面几个质量不错推荐下,实验楼有配套的练习环境。 8月22日更新:
Markdown 几乎成为了程序员编写文档的标配,解析 Markdown 文本能够加深日后编写编译器中词法分析的理解,本项目使用 C++ …
写几个folly(Facebook开源的c++库)里面的例子&br&&br&------四更,folly::future 是如何chain你的callback的 ------&br&&br&folly::future 是一个酷炫屌炸天的库,FB内部大量的异步C++的代码都是基于future的。我这段只讲他怎么支持下列语法的:&br&&br&folly::makeFuture().then([]() {&br&
// 返回一个数字&br&
return 10;&br&}).then([](int i) {&br&// 如果写 }).then([](string i) { 的话编译器会报错 &br&// 但是写 }).then([](Try&int& i) { 的话编译器不会报错
}).then([](int&& i) { 的话编译器也不会报错
}).then([](Try&int& && i) { 的话编译器也不会报错
&br&&br&});&br&&br&也就是说,callback B 是接在callbackA后面的话,callback A 如果返回的是 T,我们可以支持callback B接受 T&&, T&, T, Try&T&, Try&T&&& 废话不说先上代码。解释在代码后面,所以嫌代码长的可以直接滑过去看解释。&br&&br&&div class=&highlight&&&pre&&code class=&language-cpp&&
&span class=&cm&&/** When this Future has completed, execute func which is a function that&/span&
&span class=&cm&&
takes one of:&/span&
&span class=&cm&&
(const) Try&T&&&&/span&
&span class=&cm&&
(const) Try&T&&&/span&
&span class=&cm&&
(const) Try&T&&/span&
&span class=&cm&&
(const) T&&&/span&
&span class=&cm&&
(const) T&&/span&
&span class=&cm&&
(const) T&/span&
&span class=&cm&&
(void)&/span&
&span class=&cm&&
Func shall return either another Future or a value.&/span&
&span class=&cm&&
A Future for the return type of func is returned.&/span&
&span class=&cm&&
Future&string& f2 = f1.then([](Try&T&&&) { return string(&foo&); });&/span&
&span class=&cm&&
The Future given to the functor is ready, and the functor may call&/span&
&span class=&cm&&
value(), which may rethrow if this has captured an exception. If func&/span&
&span class=&cm&&
throws, the exception will be captured in the Future that is returned.&/span&
&span class=&cm&&
&span class=&k&&template&/span& &span class=&o&&&&/span&
&span class=&k&&typename&/span& &span class=&n&&F&/span&&span class=&p&&,&/span&
&span class=&k&&typename&/span& &span class=&n&&FF&/span& &span class=&o&&=&/span& &span class=&k&&typename&/span& &span class=&n&&detail&/span&&span class=&o&&::&/span&&span class=&n&&FunctionReferenceToPointer&/span&&span class=&o&&&&/span&&span class=&n&&F&/span&&span class=&o&&&::&/span&&span class=&n&&type&/span&&span class=&p&&,&/span&
&span class=&k&&typename&/span& &span class=&n&&R&/span& &span class=&o&&=&/span& &span class=&n&&detail&/span&&span class=&o&&::&/span&&span class=&n&&callableResult&/span&&span class=&o&&&&/span&&span class=&n&&T&/span&&span class=&p&&,&/span& &span class=&n&&FF&/span&&span class=&o&&&&&/span&
&span class=&k&&typename&/span& &span class=&n&&R&/span&&span class=&o&&::&/span&&span class=&n&&Return&/span& &span class=&n&&then&/span&&span class=&p&&(&/span&&span class=&n&&F&/span&&span class=&o&&&&&/span& &span class=&n&&func&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&k&&typedef&/span& &span class=&k&&typename&/span& &span class=&n&&R&/span&&span class=&o&&::&/span&&span class=&n&&Arg&/span& &span class=&n&&Arguments&/span&&span class=&p&&;&/span&
&span class=&k&&return&/span& &span class=&n&&thenImplementation&/span&&span class=&o&&&&/span&&span class=&n&&FF&/span&&span class=&p&&,&/span& &span class=&n&&R&/span&&span class=&o&&&&/span&&span class=&p&&(&/span&&span class=&n&&std&/span&&span class=&o&&::&/span&&span class=&n&&forward&/span&&span class=&o&&&&/span&&span class=&n&&FF&/span&&span class=&o&&&&/span&&span class=&p&&(&/span&&span class=&n&&func&/span&&span class=&p&&),&/span& &span class=&n&&Arguments&/span&&span class=&p&&());&/span&
&span class=&p&&}&/span&
&span class=&k&&template&/span&&span class=&o&&&&/span&&span class=&k&&typename&/span& &span class=&n&&F&/span&&span class=&p&&,&/span& &span class=&k&&typename&/span&&span class=&p&&...&/span& &span class=&n&&Args&/span&&span class=&o&&&&/span&
&span class=&k&&struct&/span& &span class=&n&&callableWith&/span& &span class=&p&&{&/span&
&span class=&k&&template&/span&&span class=&o&&&&/span&&span class=&k&&typename&/span& &span class=&n&&T&/span&&span class=&p&&,&/span&
&span class=&k&&typename&/span& &span class=&o&&=&/span& &span class=&n&&detail&/span&&span class=&o&&::&/span&&span class=&n&&resultOf&/span&&span class=&o&&&&/span&&span class=&n&&T&/span&&span class=&p&&,&/span& &span class=&n&&Args&/span&&span class=&p&&...&/span&&span class=&o&&&&&/span&
&span class=&k&&static&/span& &span class=&k&&constexpr&/span& &span class=&n&&std&/span&&span class=&o&&::&/span&&span class=&n&&true_type&/span&
&span class=&n&&check&/span&&span class=&p&&(&/span&&span class=&n&&std&/span&&span class=&o&&::&/span&&span class=&kt&&nullptr_t&/span&&span class=&p&&)&/span& &span class=&p&&{&/span& &span class=&k&&return&/span& &span class=&n&&std&/span&&span class=&o&&::&/span&&span class=&n&&true_type&/span&&span class=&p&&{};&/span& &span class=&p&&};&/span&
&span class=&k&&template&/span&&span class=&o&&&&/span&&span class=&k&&typename&/span&&span class=&o&&&&/span&
&span class=&k&&static&/span& &span class=&k&&constexpr&/span& &span class=&n&&std&/span&&span class=&o&&::&/span&&span class=&n&&false_type&/span&
&span class=&n&&check&/span&&span class=&p&&(...)&/span& &span class=&p&&{&/span& &span class=&k&&return&/span& &span class=&n&&std&/span&&span class=&o&&::&/span&&span class=&n&&false_type&/span&&span class=&p&&{};&/span& &span class=&p&&};&/span&
&span class=&k&&typedef&/span& &span class=&k&&decltype&/span&&span class=&p&&(&/span&&span class=&n&&check&/span&&span class=&o&&&&/span&&span class=&n&&F&/span&&span class=&o&&&&/span&&span class=&p&&(&/span&&span class=&k&&nullptr&/span&&span class=&p&&))&/span& &span class=&n&&type&/span&&span class=&p&&;&/span&
&span class=&k&&static&/span& &span class=&k&&constexpr&/span& &span class=&kt&&bool&/span& &span class=&n&&value&/span& &span class=&o&&=&/span& &span class=&n&&type&/span&&span class=&o&&::&/span&&span class=&n&&value&/span&&span class=&p&&;&/span&
&span class=&p&&};&/span&
&span class=&k&&template&/span&&span class=&o&&&&/span&&span class=&k&&typename&/span& &span class=&n&&T&/span&&span class=&p&&,&/span& &span class=&k&&typename&/span& &span class=&n&&F&/span&&span class=&o&&&&/span&
&span class=&k&&struct&/span& &span class=&n&&callableResult&/span& &span class=&p&&{&/span&
&span class=&k&&typedef&/span& &span class=&k&&typename&/span& &span class=&n&&std&/span&&span class=&o&&::&/span&&span class=&n&&conditional&/span&&span class=&o&&&&/span&
&span class=&n&&callableWith&/span&&span class=&o&&&&/span&&span class=&n&&F&/span&&span class=&o&&&::&/span&&span class=&n&&value&/span&&span class=&p&&,&/span&
&span class=&n&&detail&/span&&span class=&o&&::&/span&&span class=&n&&argResult&/span&&span class=&o&&&&/span&&span class=&nb&&false&/span&&span class=&p&&,&/span& &span class=&n&&F&/span&&span class=&o&&&&/span&&span class=&p&&,&/span&
&span class=&k&&typename&/span& &span class=&n&&std&/span&&span class=&o&&::&/span&&span class=&n&&conditional&/span&&span class=&o&&&&/span&
&span class=&n&&callableWith&/span&&span class=&o&&&&/span&&span class=&n&&F&/span&&span class=&p&&,&/span& &span class=&n&&T&/span&&span class=&o&&&&&::&/span&&span class=&n&&value&/span&&span class=&p&&,&/span&
&span class=&n&&detail&/span&&span class=&o&&::&/span&&span class=&n&&argResult&/span&&span class=&o&&&&/span&&span class=&nb&&false&/span&&span class=&p&&,&/span& &span class=&n&&F&/span&&span class=&p&&,&/span& &span class=&n&&T&/span&&span class=&o&&&&&&/span&&span class=&p&&,&/span&
&span class=&k&&typename&/span& &span class=&n&&std&/span&&span class=&o&&::&/span&&span class=&n&&conditional&/span&&span class=&o&&&&/span&
&span class=&n&&callableWith&/span&&span class=&o&&&&/span&&span class=&n&&F&/span&&span class=&p&&,&/span& &span class=&n&&T&/span&&span class=&o&&&&::&/span&&span class=&n&&value&/span&&span class=&p&&,&/span&
&span class=&n&&detail&/span&&span class=&o&&::&/span&&span class=&n&&argResult&/span&&span class=&o&&&&/span&&span class=&nb&&false&/span&&span class=&p&&,&/span& &span class=&n&&F&/span&&span class=&p&&,&/span& &span class=&n&&T&/span&&span class=&o&&&&&/span&&span class=&p&&,&/span&
&span class=&k&&typename&/span& &span class=&n&&std&/span&&span class=&o&&::&/span&&span class=&n&&conditional&/span&&span class=&o&&&&/span&
&span class=&n&&callableWith&/span&&span class=&o&&&&/span&&span class=&n&&F&/span&&span class=&p&&,&/span& &span class=&n&&Try&/span&&span class=&o&&&&/span&&span class=&n&&T&/span&&span class=&o&&&&&&::&/span&&span class=&n&&value&/span&&span class=&p&&,&/span&
&span class=&n&&detail&/span&&span class=&o&&::&/span&&span class=&n&&argResult&/span&&span class=&o&&&&/span&&span class=&nb&&true&/span&&span class=&p&&,&/span& &span class=&n&&F&/span&&span class=&p&&,&/span& &span class=&n&&Try&/span&&span class=&o&&&&/span&&span class=&n&&T&/span&&span class=&o&&&&&&&/span&&span class=&p&&,&/span&
&span class=&n&&detail&/span&&span class=&o&&::&/span&&span class=&n&&argResult&/span&&span class=&o&&&&/span&&span class=&nb&&true&/span&&span class=&p&&,&/span& &span class=&n&&F&/span&&span class=&p&&,&/span& &span class=&n&&Try&/span&&span class=&o&&&&/span&&span class=&n&&T&/span&&span class=&o&&&&&&::&/span&&span class=&n&&type&/span&&span class=&o&&&::&/span&&span class=&n&&type&/span&&span class=&o&&&::&/span&&span class=&n&&type&/span&&span class=&o&&&::&/span&&span class=&n&&type&/span& &span class=&n&&Arg&/span&&span class=&p&&;&/span&
&span class=&k&&typedef&/span& &span class=&n&&isFuture&/span&&span class=&o&&&&/span&&span class=&k&&typename&/span& &span class=&n&&Arg&/span&&span class=&o&&::&/span&&span class=&n&&Result&/span&&span class=&o&&&&/span& &span class=&n&&ReturnsFuture&/span&&span class=&p&&;&/span&
&span class=&k&&typedef&/span& &span class=&n&&Future&/span&&span class=&o&&&&/span&&span class=&k&&typename&/span& &span class=&n&&ReturnsFuture&/span&&span class=&o&&::&/span&&span class=&n&&Inner&/span&&span class=&o&&&&/span& &span class=&n&&Return&/span&&span class=&p&&;&/span&
&span class=&p&&};&/span&
&span class=&k&&template&/span&&span class=&o&&&&/span&&span class=&k&&typename&/span& &span class=&n&&F&/span&&span class=&p&&,&/span& &span class=&k&&typename&/span&&span class=&p&&...&/span& &span class=&n&&Args&/span&&span class=&o&&&&/span&
&span class=&k&&using&/span& &span class=&n&&resultOf&/span& &span class=&o&&=&/span& &span class=&k&&decltype&/span&&span class=&p&&(&/span&&span class=&n&&std&/span&&span class=&o&&::&/span&&span class=&n&&declval&/span&&span class=&o&&&&/span&&span class=&n&&F&/span&&span class=&o&&&&/span&&span class=&p&&()(&/span&&span class=&n&&std&/span&&span class=&o&&::&/span&&span class=&n&&declval&/span&&span class=&o&&&&/span&&span class=&n&&Args&/span&&span class=&o&&&&/span&&span class=&p&&()...));&/span&
&/code&&/pre&&/div&&br&这里一大波template我们一个一个来。&br&&div class=&highlight&&&pre&&code class=&language-text&&FunctionReferenceToPointer
&/code&&/pre&&/div&可以无视掉,你可以想象成FF就是F&br&&br&&a href=&///?target=http%3A///w/cpp/utility/declval& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&std::declval&i class=&icon-external&&&/i&&/a& 让你把 F变成 F&&,所以可以用&br&&div class=&highlight&&&pre&&code class=&language-cpp&&&span class=&k&&template&/span&&span class=&o&&&&/span&&span class=&k&&typename&/span& &span class=&n&&F&/span&&span class=&p&&,&/span& &span class=&k&&typename&/span&&span class=&p&&...&/span& &span class=&n&&Args&/span&&span class=&o&&&&/span&
&span class=&k&&using&/span& &span class=&n&&resultOf&/span& &span class=&o&&=&/span& &span class=&k&&decltype&/span&&span class=&p&&(&/span&&span class=&n&&std&/span&&span class=&o&&::&/span&&span class=&n&&declval&/span&&span class=&o&&&&/span&&span class=&n&&F&/span&&span class=&o&&&&/span&&span class=&p&&()(&/span&&span class=&n&&std&/span&&span class=&o&&::&/span&&span class=&n&&declval&/span&&span class=&o&&&&/span&&span class=&n&&Args&/span&&span class=&o&&&&/span&&span class=&p&&()...));&/span&
&/code&&/pre&&/div&这样的语法拿到F(Args args...) 的返回值,不管F是object还是lambda。这样,resultOf可以拿到我们的callback的返回type。现在我们得把这个返回值跟下一个函数的argument对应起来。这里我们用callableWith&br&&br&&div class=&highlight&&&pre&&code class=&language-cpp&&&span class=&k&&template&/span&&span class=&o&&&&/span&&span class=&k&&typename&/span& &span class=&n&&F&/span&&span class=&p&&,&/span& &span class=&k&&typename&/span&&span class=&p&&...&/span& &span class=&n&&Args&/span&&span class=&o&&&&/span&
&span class=&k&&struct&/span& &span class=&n&&callableWith&/span& &span class=&p&&{&/span&
&span class=&k&&template&/span&&span class=&o&&&&/span&&span class=&k&&typename&/span& &span class=&n&&T&/span&&span class=&p&&,&/span&
&span class=&k&&typename&/span& &span class=&o&&=&/span& &span class=&n&&detail&/span&&span class=&o&&::&/span&&span class=&n&&resultOf&/span&&span class=&o&&&&/span&&span class=&n&&T&/span&&span class=&p&&,&/span& &span class=&n&&Args&/span&&span class=&p&&...&/span&&span class=&o&&&&&/span&
&span class=&k&&static&/span& &span class=&k&&constexpr&/span& &span class=&n&&std&/span&&span class=&o&&::&/span&&span class=&n&&true_type&/span&
&span class=&n&&check&/span&&span class=&p&&(&/span&&span class=&n&&std&/span&&span class=&o&&::&/span&&span class=&kt&&nullptr_t&/span&&span class=&p&&)&/span& &span class=&p&&{&/span& &span class=&k&&return&/span& &span class=&n&&std&/span&&span class=&o&&::&/span&&span class=&n&&true_type&/span&&span class=&p&&{};&/span& &span class=&p&&};&/span&
&span class=&k&&template&/span&&span class=&o&&&&/span&&span class=&k&&typename&/span&&span class=&o&&&&/span&
&span class=&k&&static&/span& &span class=&k&&constexpr&/span& &span class=&n&&std&/span&&span class=&o&&::&/span&&span class=&n&&false_type&/span&
&span class=&n&&check&/span&&span class=&p&&(...)&/span& &span class=&p&&{&/span& &span class=&k&&return&/span& &span class=&n&&std&/span&&span class=&o&&::&/span&&span class=&n&&false_type&/span&&span class=&p&&{};&/span& &span class=&p&&};&/span&
&span class=&k&&typedef&/span& &span class=&k&&decltype&/span&&span class=&p&&(&/span&&span class=&n&&check&/span&&span class=&o&&&&/span&&span class=&n&&F&/span&&span class=&o&&&&/span&&span class=&p&&(&/span&&span class=&k&&nullptr&/span&&span class=&p&&))&/span& &span class=&n&&type&/span&&span class=&p&&;&/span&
&span class=&k&&static&/span& &span class=&k&&constexpr&/span& &span class=&kt&&bool&/span& &span class=&n&&value&/span& &span class=&o&&=&/span& &span class=&n&&type&/span&&span class=&o&&::&/span&&span class=&n&&value&/span&&span class=&p&&;&/span&
&span class=&p&&};&/span&
&/code&&/pre&&/div&&br&这里check有两个specialization,一个在编译时候会返回true一个会返回false。注意只要不符合第一个specialization的都是false,也就是说resultOf没有成功,check(nullptr) 就是false type。这个技巧叫做Substitution Failure Is Not An Error &a href=&///?target=http%3A///w/cpp/language/sfinae& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&SFINAE - &i class=&icon-external&&&/i&&/a& 。再配倒数第二行的typedef,如果 F可以接受args,那么callableWith&F&(Args args...)::value == true type。&br&&br&最后,把所有我们允许的类用std::conditional一个一个试过去&br&&div class=&highlight&&&pre&&code class=&language-cpp&&&span class=&k&&template&/span&&span class=&o&&&&/span&&span class=&k&&typename&/span& &span class=&n&&T&/span&&span class=&p&&,&/span& &span class=&k&&typename&/span& &span class=&n&&F&/span&&span class=&o&&&&/span&
&span class=&k&&struct&/span& &span class=&n&&callableResult&/span& &span class=&p&&{&/span&
&span class=&k&&typedef&/span& &span class=&k&&typename&/span& &span class=&n&&std&/span&&span class=&o&&::&/span&&span class=&n&&conditional&/span&&span class=&o&&&&/span&
&span class=&n&&callableWith&/span&&span class=&o&&&&/span&&span class=&n&&F&/span&&span class=&o&&&::&/span&&span class=&n&&value&/span&&span class=&p&&,&/span&
&span class=&n&&detail&/span&&span class=&o&&::&/span&&span class=&n&&argResult&/span&&span class=&o&&&&/span&&span class=&nb&&false&/span&&span class=&p&&,&/span& &span class=&n&&F&/span&&span class=&o&&&&/span&&span class=&p&&,&/span&
&span class=&k&&typename&/span& &span class=&n&&std&/span&&span class=&o&&::&/span&&span class=&n&&conditional&/span&&span class=&o&&&&/span&
&span class=&n&&callableWith&/span&&span class=&o&&&&/span&&span class=&n&&F&/span&&span class=&p&&,&/span& &span class=&n&&T&/span&&span class=&o&&&&&::&/span&&span class=&n&&value&/span&&span class=&p&&,&/span&
&span class=&n&&detail&/span&&span class=&o&&::&/span&&span class=&n&&argResult&/span&&span class=&o&&&&/span&&span class=&nb&&false&/span&&span class=&p&&,&/span& &span class=&n&&F&/span&&span class=&p&&,&/span& &span class=&n&&T&/span&&span class=&o&&&&&&/span&&span class=&p&&,&/span&
&span class=&k&&typename&/span& &span class=&n&&std&/span&&span class=&o&&::&/span&&span class=&n&&conditional&/span&&span class=&o&&&&/span&
&span class=&n&&callableWith&/span&&span class=&o&&&&/span&&span class=&n&&F&/span&&span class=&p&&,&/span& &span class=&n&&T&/span&&span class=&o&&&&::&/span&&span class=&n&&value&/span&&span class=&p&&,&/span&
&span class=&n&&detail&/span&&span class=&o&&::&/span&&span class=&n&&argResult&/span&&span class=&o&&&&/span&&span class=&nb&&false&/span&&span class=&p&&,&/span& &span class=&n&&F&/span&&span class=&p&&,&/span& &span class=&n&&T&/span&&span class=&o&&&&&/span&&span class=&p&&,&/span&
&span class=&k&&typename&/span& &span class=&n&&std&/span&&span class=&o&&::&/span&&span class=&n&&conditional&/span&&span class=&o&&&&/span&
&span class=&n&&callableWith&/span&&span class=&o&&&&/span&&span class=&n&&F&/span&&span class=&p&&,&/span& &span class=&n&&Try&/span&&span class=&o&&&&/span&&span class=&n&&T&/span&&span class=&o&&&&&&::&/span&&span class=&n&&value&/span&&span class=&p&&,&/span&
&span class=&n&&detail&/span&&span class=&o&&::&/span&&span class=&n&&argResult&/span&&span class=&o&&&&/span&&span class=&nb&&true&/span&&span class=&p&&,&/span& &span class=&n&&F&/span&&span class=&p&&,&/span& &span class=&n&&Try&/span&&span class=&o&&&&/span&&span class=&n&&T&/span&&span class=&o&&&&&&&/span&&span class=&p&&,&/span&
&span class=&n&&detail&/span&&span class=&o&&::&/span&&span class=&n&&argResult&/span&&span class=&o&&&&/span&&span class=&nb&&true&/span&&span class=&p&&,&/span& &span class=&n&&F&/span&&span class=&p&&,&/span& &span class=&n&&Try&/span&&span class=&o&&&&/span&&span class=&n&&T&/span&&span class=&o&&&&&&::&/span&&span class=&n&&type&/span&&span class=&o&&&::&/span&&span class=&n&&type&/span&&span class=&o&&&::&/span&&span class=&n&&type&/span&&span class=&o&&&::&/span&&span class=&n&&type&/span& &span class=&n&&Arg&/span&&span class=&p&&;&/span&
&span class=&k&&typedef&/span& &span class=&n&&isFuture&/span&&span class=&o&&&&/span&&span class=&k&&typename&/span& &span class=&n&&Arg&/span&&span class=&o&&::&/span&&span class=&n&&Result&/span&&span class=&o&&&&/span& &span class=&n&&ReturnsFuture&/span&&span class=&p&&;&/span&
&span class=&k&&typedef&/span& &span class=&n&&Future&/span&&span class=&o&&&&/span&&span class=&k&&typename&/span& &span class=&n&&ReturnsFuture&/span&&span class=&o&&::&/span&&span class=&n&&Inner&/span&&span class=&o&&&&/span& &span class=&n&&Return&/span&&span class=&p&&;&/span&
&span class=&p&&};&/span&
&/code&&/pre&&/div&我们就可以在编译时间确保我们可以支持我们所有想支持的7个类啦。那具体拿着第一个callback的返回值怎么传输到第二个callback上面做argument呢?这一段变种太多,我只给大家看最简单的变种:&br&&br&&div class=&highlight&&&pre&&code class=&language-cpp&&&span class=&c1&&// Variant: returns a value&/span&
&span class=&c1&&// e.g. f.then([](Try&T&&& t){ return t.value(); });&/span&
&span class=&k&&template&/span& &span class=&o&&&&/span&&span class=&k&&class&/span& &span class=&nc&&T&/span&&span class=&o&&&&/span&
&span class=&k&&template&/span& &span class=&o&&&&/span&&span class=&k&&typename&/span& &span class=&n&&F&/span&&span class=&p&&,&/span& &span class=&k&&typename&/span& &span class=&n&&R&/span&&span class=&p&&,&/span& &span class=&kt&&bool&/span& &span class=&n&&isTry&/span&&span class=&p&&,&/span& &span class=&k&&typename&/span&&span class=&p&&...&/span& &span class=&n&&Args&/span&&span class=&o&&&&/span&
&span class=&k&&typename&/span& &span class=&n&&std&/span&&span class=&o&&::&/span&&span class=&n&&enable_if&/span&&span class=&o&&&!&/span&&span class=&n&&R&/span&&span class=&o&&::&/span&&span class=&n&&ReturnsFuture&/span&&span class=&o&&::&/span&&span class=&n&&value&/span&&span class=&p&&,&/span& &span class=&k&&typename&/span& &span class=&n&&R&/span&&span class=&o&&::&/span&&span class=&n&&Return&/span&&span class=&o&&&::&/span&&span class=&n&&type&/span&
&span class=&n&&Future&/span&&span class=&o&&&&/span&&span class=&n&&T&/span&&span class=&o&&&::&/span&&span class=&n&&thenImplementation&/span&&span class=&p&&(&/span&&span class=&n&&F&/span&&span class=&o&&&&&/span& &span class=&n&&func&/span&&span class=&p&&,&/span& &span class=&n&&detail&/span&&span class=&o&&::&/span&&span class=&n&&argResult&/span&&span class=&o&&&&/span&&span class=&n&&isTry&/span&&span class=&p&&,&/span& &span class=&n&&F&/span&&span class=&p&&,&/span& &span class=&n&&Args&/span&&span class=&p&&...&/span&&span class=&o&&&&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&k&&static_assert&/span&&span class=&p&&(&/span&&span class=&k&&sizeof&/span&&span class=&p&&...(&/span&&span class=&n&&Args&/span&&span class=&p&&)&/span& &span class=&o&&&=&/span& &span class=&mi&&1&/span&&span class=&p&&,&/span& &span class=&s&&&Then must take zero/one argument&&/span&&span class=&p&&);&/span&
&span class=&k&&typedef&/span& &span class=&k&&typename&/span& &span class=&n&&R&/span&&span class=&o&&::&/span&&span class=&n&&ReturnsFuture&/span&&span class=&o&&::&/span&&span class=&n&&Inner&/span& &span class=&n&&B&/span&&span class=&p&&;&/span&
&span class=&n&&throwIfInvalid&/span&&span class=&p&&();&/span&
&span class=&n&&Promise&/span&&span class=&o&&&&/span&&span class=&n&&B&/span&&span class=&o&&&&/span& &span class=&n&&p&/span&&span class=&p&&;&/span&
&span class=&n&&p&/span&&span class=&p&&.&/span&&span class=&n&&core_&/span&&span class=&o&&-&&/span&&span class=&n&&setInterruptHandlerNoLock&/span&&span class=&p&&(&/span&&span class=&n&&core_&/span&&span class=&o&&-&&/span&&span class=&n&&getInterruptHandler&/span&&span class=&p&&());&/span&
&span class=&c1&&// grab the Future now before we lose our handle on the Promise&/span&
&span class=&k&&auto&/span& &span class=&n&&f&/span& &span class=&o&&=&/span& &span class=&n&&p&/span&&span class=&p&&.&/span&&span class=&n&&getFuture&/span&&span class=&p&&();&/span&
&span class=&n&&f&/span&&span class=&p&&.&/span&&span class=&n&&core_&/span&&span class=&o&&-&&/span&&span class=&n&&setExecutorNoLock&/span&&span class=&p&&(&/span&&span class=&n&&getExecutor&/span&&span class=&p&&());&/span&
&span class=&c1&&// 这里注释省略,因为实在太长。&/span&
&span class=&n&&setCallback_&/span&&span class=&p&&([&/span& &span class=&n&&funcm&/span& &span class=&o&&=&/span& &span class=&n&&std&/span&&span class=&o&&::&/span&&span class=&n&&forward&/span&&span class=&o&&&&/span&&span class=&n&&F&/span&&span class=&o&&&&/span&&span class=&p&&(&/span&&span class=&n&&func&/span&&span class=&p&&),&/span& &span class=&n&&pm&/span& &span class=&o&&=&/span& &span class=&n&&std&/span&&span class=&o&&::&/span&&span class=&n&&move&/span&&span class=&p&&(&/span&&span class=&n&&p&/span&&span class=&p&&)&/span& &span class=&p&&](&/span&
&span class=&n&&Try&/span&&span class=&o&&&&/span&&span class=&n&&T&/span&&span class=&o&&&&/span& &span class=&o&&&&&/span& &span class=&n&&t&/span&&span class=&p&&)&/span& &span class=&k&&mutable&/span& &span class=&p&&{&/span&
&span class=&k&&if&/span& &span class=&p&&(&/span&&span class=&o&&!&/span&&span class=&n&&isTry&/span& &span class=&o&&&&&/span& &span class=&n&&t&/span&&span class=&p&&.&/span&&span class=&n&&hasException&/span&&span class=&p&&())&/span& &span class=&p&&{&/span&
&span class=&n&&pm&/span&&span class=&p&&.&/span&&span class=&n&&setException&/span&&span class=&p&&(&/span&&span class=&n&&std&/span&&span class=&o&&::&/span&&span class=&n&&move&/span&&span class=&p&&(&/span&&span class=&n&&t&/span&&span class=&p&&.&/span&&span class=&n&&exception&/span&&span class=&p&&()));&/span&
&span class=&p&&}&/span& &span class=&k&&else&/span& &span class=&p&&{&/span&
&span class=&n&&pm&/span&&span class=&p&&.&/span&&span class=&n&&setWith&/span&&span class=&p&&([&/span&&span class=&o&&&&/span&&span class=&p&&]()&/span& &span class=&p&&{&/span& &span class=&k&&return&/span& &span class=&n&&funcm&/span&&span class=&p&&(&/span&&span class=&n&&t&/span&&span class=&p&&.&/span&&span class=&k&&template&/span& &span class=&n&&get&/span&&span class=&o&&&&/span&&span class=&n&&isTry&/span&&span class=&p&&,&/span& &span class=&n&&Args&/span&&span class=&o&&&&/span&&span class=&p&&()...);&/span& &span class=&p&&});&/span&
&span class=&p&&}&/span&
&span class=&p&&});&/span&
&span class=&k&&return&/span& &span class=&n&&f&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&span class=&k&&template&/span& &span class=&o&&&&/span&&span class=&k&&class&/span& &span class=&nc&&T&/span&&span class=&o&&&&/span&
&span class=&k&&template&/span& &span class=&o&&&&/span&&span class=&k&&class&/span& &span class=&nc&&F&/span&&span class=&o&&&&/span&
&span class=&kt&&void&/span& &span class=&n&&Future&/span&&span class=&o&&&&/span&&span class=&n&&T&/span&&span class=&o&&&::&/span&&span class=&n&&setCallback_&/span&&span class=&p&&(&/span&&span class=&n&&F&/span&&span class=&o&&&&&/span& &span class=&n&&func&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&n&&throwIfInvalid&/span&&span class=&p&&();&/span&
&span class=&n&&core_&/span&&span class=&o&&-&&/span&&span class=&n&&setCallback&/span&&span class=&p&&(&/span&&span class=&n&&std&/span&&span class=&o&&::&/span&&span class=&n&&forward&/span&&span class=&o&&&&/span&&span class=&n&&F&/span&&span class=&o&&&&/span&&span class=&p&&(&/span&&span class=&n&&func&/span&&span class=&p&&));&/span&
&span class=&p&&}&/span&
&span class=&k&&protected&/span&&span class=&o&&:&/span&
&span class=&k&&typedef&/span& &span class=&n&&detail&/span&&span class=&o&&::&/span&&span class=&n&&Core&/span&&span class=&o&&&&/span&&span class=&n&&T&/span&&span class=&o&&&*&/span& &span class=&n&&corePtr&/span&&span class=&p&&;&/span&
&span class=&c1&&// shared core state object&/span&
&span class=&n&&corePtr&/span& &span class=&n&&core_&/span&&span class=&p&&;&/span&
&/code&&/pre&&/div&&br&core_ 是future 的member,也就是说我们设置的callback仅仅只是被加到callback里面去了,还没有被执行。只有当你执行future.get() 的时候值才会被你拿到&br&&br&&div class=&highlight&&&pre&&code class=&language-cpp&&&span class=&k&&template&/span& &span class=&o&&&&/span&&span class=&k&&class&/span& &span class=&nc&&T&/span&&span class=&o&&&&/span&
&span class=&n&&T&/span& &span class=&n&&Future&/span&&span class=&o&&&&/span&&span class=&n&&T&/span&&span class=&o&&&::&/span&&span class=&n&&get&/span&&span class=&p&&()&/span& &span class=&p&&{&/span&
&span class=&k&&return&/span& &span class=&n&&std&/span&&span class=&o&&::&/span&&span class=&n&&move&/span&&span class=&p&&(&/span&&span class=&n&&wait&/span&&span class=&p&&().&/span&&span class=&n&&value&/span&&span class=&p&&());&/span&
&span class=&p&&}&/span&
&span class=&k&&template&/span& &span class=&o&&&&/span&&span class=&k&&class&/span& &span class=&nc&&T&/span&&span class=&o&&&&/span&
&span class=&n&&Future&/span&&span class=&o&&&&/span&&span class=&n&&T&/span&&span class=&o&&&&&/span& &span class=&n&&Future&/span&&span class=&o&&&&/span&&span class=&n&&T&/span&&span class=&o&&&::&/span&&span class=&n&&wait&/span&&span class=&p&&()&/span& &span class=&o&&&&/span& &span class=&p&&{&/span&
&span class=&n&&detail&/span&&span class=&o&&::&/span&&span class=&n&&waitImpl&/span&&span class=&p&&(&/span&&span class=&o&&*&/span&&span class=&k&&this&/span&&span class=&p&&);&/span&
&span class=&k&&return&/span& &span class=&o&&*&/span&&span class=&k&&this&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&span class=&k&&template&/span& &span class=&o&&&&/span&&span class=&k&&class&/span& &span class=&nc&&T&/span&&span class=&o&&&&/span&
&span class=&kt&&void&/span& &span class=&n&&waitImpl&/span&&span class=&p&&(&/span&&span class=&n&&Future&/span&&span class=&o&&&&/span&&span class=&n&&T&/span&&span class=&o&&&&&/span& &span class=&n&&f&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&c1&&// short-circuit if there's nothing to do&/span&
&span class=&k&&if&/span& &span class=&p&&(&/span&&span class=&n&&f&/span&&span class=&p&&.&/span&&span class=&n&&isReady&/span&&span class=&p&&())&/span& &span class=&k&&return&/span&&span class=&p&&;&/span&
&span class=&n&&FutureBatonType&/span& &span class=&n&&baton&/span&&span class=&p&&;&/span&
&span class=&n&&f&/span&&span class=&p&&.&/span&&span class=&n&&setCallback_&/span&&span class=&p&&([&/span&&span class=&o&&&&/span&&span class=&p&&](&/span&&span class=&k&&const&/span& &span class=&n&&Try&/span&&span class=&o&&&&/span&&span class=&n&&T&/span&&span class=&o&&&&&/span& &span class=&cm&&/* t */&/span&&span class=&p&&)&/span& &span class=&p&&{&/span& &span class=&n&&baton&/span&&span class=&p&&.&/span&&span class=&n&&post&/span&&span class=&p&&();&/span& &span class=&p&&});&/span&
&span class=&n&&baton&/span&&span class=&p&&.&/span&&span class=&n&&wait&/span&&span class=&p&&();&/span&
&span class=&n&&assert&/span&&span class=&p&&(&/span&&span class=&n&&f&/span&&span class=&p&&.&/span&&span class=&n&&isReady&/span&&span class=&p&&());&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&br&啊,所有的callback执行都被扔到baton里面去了,我先不在这里继续深挖了。总之&br&&br&auto value = folly::makeFuture(cb1).then(cb2).get();&br&&br&- 在编译的时候,是通过一系列declval/decltype/SFAINE/std::conditional 来确保类是对的&br&- 在运行的时候 cb1被传到future.core_ -& baton -& 拿到值 -& 根据cb2是不是接受try来分叉 -& 值扔给 cb2&br&我把Promise/Baton的内容全部跳过去了,因为要把那两个也讲了就没完没了了,在template metaprogramming上面也没有future这么fancy。以后有机会再细写那两个库吧!&br&&br&&br&--------三更,讲点稍微实用一点的数据结构吧, 两个看起来风马牛不相及其实储存上一致的folly::Optional 和 folly::Indestructible ------&br&&br&&b&folly::Optional&/b&&br&&a href=&///?target=https%3A///facebook/folly/blob/master/folly/Optional.h& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&folly/Optional.h at master · facebook/folly · GitHub&i class=&icon-external&&&/i&&/a&&br&c++里面不是所有的类都可以是null的,特别有的时候这个类是其他人硬塞给你的。而当你需要它可是你null的时候,你把这个类放到folly optional里面,它就可以是null啦。folly optional里面比较有意思的是它储存的机制&br&&br&&div class=&highlight&&&pre&&code class=&language-cpp&&
&span class=&k&&using&/span& &span class=&n&&Storage&/span& &span class=&o&&=&/span& &span class=&k&&typename&/span& &span class=&n&&std&/span&&span class=&o&&::&/span&&span class=&n&&conditional&/span&&span class=&o&&&&/span&&span class=&n&&std&/span&&span class=&o&&::&/span&&span class=&n&&is_trivially_destructible&/span&&span class=&o&&&&/span&&span class=&n&&Value&/span&&span class=&o&&&::&/span&&span class=&n&&value&/span&&span class=&p&&,&/span&
&span class=&n&&StorageTriviallyDestructible&/span&&span class=&p&&,&/span&
&span class=&n&&StorageNonTriviallyDestructible&/span&&span class=&o&&&::&/span&&span class=&n&&type&/span&&span class=&p&&;&/span&
&span class=&n&&Storage&/span& &span class=&n&&storage_&/span&&span class=&p&&;&/span&
&span class=&k&&struct&/span& &span class=&n&&StorageTriviallyDestructible&/span& &span class=&p&&{&/span&
&span class=&c1&&// uninitialized&/span&
&span class=&n&&uniocn&/span& &span class=&p&&{&/span& &span class=&n&&Value&/span& &span class=&n&&value&/span&&span class=&p&&;&/span& &span class=&p&&};&/span&
&span class=&kt&&bool&/span& &span class=&n&&hasValue&/span&&span class=&p&&;&/span&
&span class=&n&&StorageTriviallyDestructible&/span&&span class=&p&&()&/span& &span class=&o&&:&/span& &span class=&n&&hasValue&/span&&span class=&p&&{&/span&&span class=&nb&&false&/span&&span class=&p&&}&/span& &span class=&p&&{}&/span&
&span class=&kt&&void&/span& &span class=&n&&clear&/span&&span class=&p&&()&/span& &span class=&p&&{&/span&
&span class=&n&&hasValue&/span& &span class=&o&&=&/span& &span class=&nb&&false&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&span class=&p&&};&/span&
&span class=&k&&struct&/span& &span class=&n&&StorageNonTriviallyDestructible&/span& &span class=&p&&{&/span&
&span class=&c1&&// uninitialized&/span&
&span class=&k&&union&/span& &span class=&p&&{&/span& &span class=&n&&Value&/span& &span class=&n&&value&/span&&span class=&p&&;&/span& &span class=&p&&};&/span&
&span class=&kt&&bool&/span& &span class=&n&&hasValue&/span&&span class=&p&&;&/span&
&span class=&n&&StorageNonTriviallyDestructible&/span&&span class=&p&&()&/span& &span class=&o&&:&/span& &span class=&n&&hasValue&/span&&span class=&p&&{&/span&&span class=&nb&&false&/span&&span class=&p&&}&/span& &span class=&p&&{}&/span&
&span class=&o&&~&/span&&span class=&n&&StorageNonTriviallyDestructible&/span&&span class=&p&&()&/span& &span class=&p&&{&/span&
&span class=&n&&clear&/span&&span class=&p&&();&/span&
&span class=&p&&}&/span&
&span class=&kt&&void&/span& &span class=&n&&clear&/span&&span class=&p&&()&/span& &span class=&p&&{&/span&
&span class=&k&&if&/span& &span class=&p&&(&/span&&span class=&n&&hasValue&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&n&&hasValue&/span& &span class=&o&&=&/span& &span class=&nb&&false&/span&&span class=&p&&;&/span&
&span class=&n&&value&/span&&span class=&p&&.&/span&&span class=&o&&~&/span&&span class=&n&&Value&/span&&span class=&p&&();&/span&
&span class=&p&&}&/span&
&span class=&p&&}&/span&
&span class=&p&&};&/span&
&/code&&/pre&&/div&&br&StorageTriviallyDestructible 还稍微合理一点,StorageNonTriviallyDestructible.clear() 里面~Value() 绝对很少见。这是c++11里面unconstrained union的新玩法,因为在unconstrained union里面你必须有能力可以销毁一个non-POD类,所以c++语法开放了~Value() 这种语法,让你可以销毁这个值。这个功能在这里就被弄出了新玩法,被用来支持folly::Optional.clear(),这样就算是一个NonTriviallyDestructible的对象你也可以随时销毁它。&br&&br&这种unconstrained union的启动机制也是比较麻烦的。folly::optional.set 长这样:&br&&br&&div class=&highlight&&&pre&&code class=&language-text&&
template&class... Args&
void construct(Args&&... args) {
const void* ptr = &storage_.
// for supporting const types
new(const_cast&void*&(ptr)) Value(std::forward&Args&(args)...);
storage_.hasValue =
&/code&&/pre&&/div&&br&&div class=&highlight&&&pre&&code class=&language-text&&
new(const_cast&void*&(ptr)) Value(std::forward&Args&(args)...);
&/code&&/pre&&/div&这个叫placement new,就是说你给new 一个地址,new直接在你给的地址上面initialize,而不是去heap里面占内存。有上面两个玩法的话,你就可以随时随地在c++启动,销毁这个值啦!&br&&br&&b&folly::Indestructible&/b&&br&如何确保你的meyer's singleton永远不死?这样储存你的类:&br&&br&&div class=&highlight&&&pre&&code class=&language-text&&
union Storage {
template &typename... Args&
explicit constexpr Storage(Args&&... args)
: value(std::forward&Args&(args)...) {}
~Storage() {}
&/code&&/pre&&/div&看起来好像没有什么特殊的对不对?不要忘记这个T在这里肯定是个non trivially destructable的类。在这个union里面,既然你的destructor是空的,那么也就是说value永远被遗忘了。。。遗忘了。。。遗忘了。。&br&&br&看到这里有人要开骂了,为什么不直接new一个值出来,不销毁就好了?这跟new一个新的值出来最大的差别是这个不可以被遗忘的值是可以被inline的,它用的内存不是heap里面的内存(至少value本身不在heap上面)。这在效率上的差别是不可小觑的。&br&&br&folly::optional 跟 folly::indestructable 都是利用了新标准里面union的新特性。看来新玩法还是要多想&br&&br&&br&---------谢谢各位踊跃点赞,这段是二更。要是过一千的话我就写MPMCQueue哦--------&br&folly::Conv 是可以把所有类转化成所有类的库。也不是所有啦,不过正常人用的到的都有。我这里只讲int转字符串,float/double 实在太麻烦。&br&先看数字转字符串里面算多少位数的&br&&br&&div class=&highlight&&&pre&&code class=&language-text&&/**
* Returns the number of digits in the base 10 representation of an
* uint64_t. Useful for preallocating buffers and such. It's also used
* internally, see below. Measurements suggest that defining a
* separate overload for 32-bit integers is not worthwhile.
inline uint32_t digits10(uint64_t v) {
#ifdef __x86_64__
// For this arch we can get a little help from specialized CPU instructions
// which can
64 minus that is appx. log (base 2).
// Use that to approximate base-10 digits (log_10) and then adjust if needed.
// 10^i, defined for i 0 through 19.
// This is 20 * 8 == 160 bytes, which fits neatly into 5 cache lines
// (assuming a cache line size of 64).
static const uint64_t powersOf10[20] FOLLY_ALIGNED(64) = {
// &count leading zeroes& for 0; special case this.
if UNLIKELY (!v) {
// bits is in the ballpark of log_2(v).
const uint8_t leadingZeroes = __builtin_clzll(v);
const auto bits = 63 - leadingZ
// approximate log_10(v) == log_10(2) * bits.
// Integer magic below: 77/256 is appx. 0.3010 (log_10(2)).
// The +1 is to make this the ceiling of the log_10 estimate.
const uint32_t minLength = 1 + ((bits * 77) && 8);
// return that log_10 lower bound, plus adjust if input &= 10^(that bound)
// in case there's a small error and we misjudged length.
return minLength + (uint32_t) (UNLIKELY (v &= powersOf10[minLength]));
uint32_t result = 1;
for (;;) {
if (LIKELY(v & 10))
if (LIKELY(v & 100)) return result + 1;
if (LIKELY(v & 1000)) return result + 2;
if (LIKELY(v & 10000)) return result + 3;
// Skip ahead by 4 orders of magnitude
v /= 10000U;
result += 4;
&/code&&/pre&&/div&&br&下面那个for loop多友好,上面x86那段是什么鬼!&br&builtin_clzll 是gcc里面的一个函数,具体定义看这里&a href=&///?target=https%3A//gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Other Builtins&i class=&icon-external&&&/i&&/a& 简单来说就是算有几个开头的0的。这里面的0是2进制的0,所以63-leading zeros就是说二进制里面有几位数。&br&&div class=&highlight&&&pre&&code class=&language-text&&
const uint32_t minLength = 1 + ((bits * 77) && 8);
&/code&&/pre&&/div&这个就是亮点了。高中数学没学好的话,这里强调一下&br&log_10(v) =log_10(2) * log_2(v) (&a href=&///?target=http%3A///modules/logrules5.htm& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&The Change-of-Base Formula&i class=&icon-external&&&/i&&/a&)&br&&& 8 就是处以256&br&bits在这里已经是log(2)了&br&+1是因为 0.3010略小于77/256&br&&br&我们继续瞎,现在开始正式转换&br&&br&&div class=&highlight&&&pre&&code class=&language-text&&/**
* Copies the ASCII base 10 representation of v into buffer and
* returns the number of bytes written. Does NOT append a \0. Assumes
* the buffer points to digits10(v) bytes of valid memory. Note that
* uint64 needs at most 20 bytes, uint32_t needs at most 10 bytes,
* uint16_t needs at most 5 bytes, and so on. Measurements suggest
* that defining a separate overload for 32-bit integers is not
* worthwhile.
* This primitive is unsafe because it makes the size assumption and
* because it does not add a terminating \0.
inline uint32_t uint64ToBufferUnsafe(uint64_t v, char *const buffer) {
auto const result = digits10(v);
// WARNING: using size_t or pointer arithmetic for pos slows down
// the loop below 20x. This is because several 32-bit ops can be
// done in parallel, but only fewer 64-bit ones.
uint32_t pos = result - 1;
while (v &= 10) {
// Keep these together so a peephole optimization &sees& them and
// computes them in one shot.
auto const q = v / 10;
auto const r = static_cast&uint32_t&(v % 10);
buffer[pos--] = '0' +
// Last digit is trivial to handle
buffer[pos] = static_cast&uint32_t&(v) + '0';
&/code&&/pre&&/div&&br&这里面开始甩说用pos慢了,估计原因是loop unrolling做不了,但是具体不好说,我得问问他。&br&peephole optimization简单来说就是一段短小精悍的代码可以被compiler 变得更短小精悍(&a href=&///?target=https%3A//en.wikipedia.org/wiki/Peephole_optimization& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Peephole optimization&i class=&icon-external&&&/i&&/a&),具体肯定也是实测过才敢拿出来讲。非常好读懂我就不BB了。不过用C++用的熟练的看到这种不差buffer大小的肯定非常不爽。为什么可以不查?!&br&&br&&br&&div class=&highlight&&&pre&&code class=&language-text&&/**
* int32_t and int64_t to string (by appending) go through here. The
* result is APPENDED to a preexisting string passed as the second
* parameter. This should be efficient with fbstring because fbstring
* incurs no dynamic allocation below 23 bytes and no number has more
* than 22 bytes in its textual representation (20 for digits, one for
* sign, one for the terminating 0).
template &class Tgt, class Src&
typename std::enable_if&
std::is_integral&Src&::value && std::is_signed&Src&::value &&
IsSomeString&Tgt&::value && sizeof(Src) &= 4&::type
toAppend(Src value, Tgt * result) {
char buffer[20];
if (value & 0) {
result-&push_back('-');
result-&append(buffer, uint64ToBufferUnsafe(-uint64_t(value), buffer));
result-&append(buffer, uint64ToBufferUnsafe(value, buffer));
&/code&&/pre&&/div&&br&好了我服了。。。&br&&br&&br&-----------------------原先的答案------------------------------&br&&b&AtomicStruct&/b&&br&&a href=&///?target=https%3A///facebook/folly/blob/master/folly/AtomicStruct.h& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&folly/AtomicStruct.h at master · facebook/folly · GitHub&i class=&icon-external&&&/i&&/a&&br&&br&类似于std::atomic, 但是任何小于8个byte的POD类都可以变成atomic的。实现的方法如下:&br&用一个unconstrained union 来存数据:&br&&div class=&highlight&&&pre&&code class=&language-text&&union {
&/code&&/pre&&/div&&br&T是你的类,Atom 就是std::atomic,Raw是这么来的&br&&div class=&highlight&&&pre&&code class=&language-text&&typename Raw = typename detail::AtomicStructIntPick&sizeof(T)&::type
&/code&&/pre&&/div&&div class=&highlight&&&pre&&code class=&language-text&&template && struct AtomicStructIntPick&1& { typedef uint8_ };
template && struct AtomicStructIntPick&2& { typedef uint16_ };
template && struct AtomicStructIntPick&3& { typedef uint32_ };
template && struct AtomicStructIntPick&4& { typedef uint32_ };
template && struct AtomicStructIntPick&5& { typedef uint64_ };
template && struct AtomicStructIntPick&6& { typedef uint64_ };
template && struct AtomicStructIntPick&7& { typedef uint64_ };
template && struct AtomicStructIntPick&8& { typedef uint64_ };
&/code&&/pre&&/div&我看到这里已经开始瞎了。&br&compare exchange是这样的&br&&div class=&highlight&&&pre&&code class=&language-text&&
bool compare_exchange_weak(
T& v0, T v1,
std::memory_order mo = std::memory_order_seq_cst) noexcept {
Raw d0 = encode(v0);
bool rv = pare_exchange_weak(d0, encode(v1), mo);
if (!rv) {
v0 = decode(d0);
&/code&&/pre&&/div&&br&里面的encode/decode就是拿来骗编译器的memcpy。写了这么多废话,说白了就是为了让编译器开心的可以用各种std::atomc&int&&br&&br&&b&DiscriminatedPtr&/b&&br&用法就是boost::variant,但是用DiscriminatedPtr没有任何多余的代价,就是一个指针的大小。为什么可以没有代价呢?应为64位系统里面其实只有48位拿来做地址了,剩下16位是没有被系统用起来的。所以要地址是这么读的&br&&br&&div class=&highlight&&&pre&&code class=&language-text&&
void* ptr() const {
return reinterpret_cast&void*&(data_ & ((1ULL && 48) - 1));
&/code&&/pre&&/div&&br&&br&那前16个bit是存什么呢?存的是现有这个类的index。每次存的时候,会通过index找到对应的类&br&&br&&div class=&highlight&&&pre&&code class=&language-text&&
* Set this DiscriminatedPtr to point to an object of type T.
* Fails at compile time if T is not a valid type (listed in Types)
template &typename T&
void set(T* ptr) {
set(ptr, typeIndex&T&());
&/code&&/pre&&/div&&br&然后&br&&br&&div class=&highlight&&&pre&&code class=&language-text&&
void set(void* p, uint16_t v) {
uintptr_t ip = reinterpret_cast&uintptr_t&(p);
CHECK(!(ip && 48));
ip |= static_cast&uintptr_t&(v) && 48;
&/code&&/pre&&/div&&br&那typeIndex是什么鬼!?typeIndex是一个编译是通过递归制造出来的列表,可以在编译时制造出一个数字对应类的列表&br&&div class=&highlight&&&pre&&code class=&language-text&&template &typename... Types& struct GetTypeI
template &typename T, typename... Types&
struct GetTypeIndex&T, T, Types...& {
static const size_t value = 1;
template &typename T, typename U, typename... Types&
struct GetTypeIndex&T, U, Types...& {
static const size_t value = 1 + GetTypeIndex&T, Types...&::
&/code&&/pre&&/div&&br&具体实现在这里&a href=&///?target=https%3A///facebook/folly/blob/master/folly/detail/DiscriminatedPtrDetail.h%23L33& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&folly/DiscriminatedPtrDetail.h at master · facebook/folly · GitHub&i class=&icon-external&&&/i&&/a&。 这样在编译时间你就可以知道你要的类是不是这个指针支持的类。要是对编译时的黑魔法感兴趣的话,可以从boost的index_sequence看起 &a href=&///?target=http%3A//www.boost.org/doc/libs/1_60_0/boost/fusion/support/detail/index_sequence.hpp& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&boost/fusion/support/detail/index_sequence.hpp&i class=&icon-external&&&/i&&/a&&br&DiscriminatedPtr还支持visitor pattern,具体这里不细讲应为没有什么typeIndex以外的黑科技。具体用法可以参照boost::invariant &a href=&///?target=http%3A//www.boost.org/doc/libs/1_61_0/doc/html/variant/tutorial.html%23variant.tutorial.basic& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Tutorial - 1.61.0&i class=&icon-external&&&/i&&/a&&br&&br&先写着么多,要是有人看的话我就继续写。你们可得用力点赞啊!
写几个folly(Facebook开源的c++库)里面的例子 ------四更,folly::future 是如何chain你的callback的 ------ folly::future 是一个酷炫屌炸天的库,FB内部大量的异步C++的代码都是基于future的。我这段只讲他怎么支持下列语法的: folly::makeFuture().th…
&img src=&/50/v2-f5d72828fbd36e2d01aa5f_b.jpg& data-rawwidth=&788& data-rawheight=&442& class=&origin_image zh-lightbox-thumb& width=&788& data-original=&/50/v2-f5d72828fbd36e2d01aa5f_r.jpg&&利用数组,我们可以在空战游戏中实现多台敌机、发射闪弹等效果。大家可以用之前教程的思路,尝试分步骤实现:飞机的显示、单个敌机、多个敌机、发射常规子弹、发射闪弹,以下是完整的代码。&img src=&/v2-a4aa06cd2ebfa4c267c64_b.png& data-rawwidth=&419& data-rawheight=&565& class=&content_image& width=&419&&&div class=&highlight&&&pre&&code class=&language-c&&&span&&/span&&span class=&cp&&#include&/span& &span class=&cpf&&&stdio.h&&/span&&span class=&cp&&&/span&
&span class=&cp&&#include&/span& &span class=&cpf&&&stdlib.h&&/span&&span class=&cp&&&/span&
&span class=&cp&&#include&/span& &span class=&cpf&&&conio.h&&/span&&span class=&cp&&&/span&
&span class=&cp&&#include&/span& &span class=&cpf&&&windows.h&&/span&&span class=&cp&&&/span&
&span class=&cp&&#define High 15
&/span&&span class=&c1&&// 游戏画面尺寸&/span&
&span class=&cp&&#define Width 25&/span&
&span class=&cp&&#define EnemyNum 5 &/span&&span class=&c1&&// 敌机个数&/span&
&span class=&c1&&// 全局变量&/span&
&span class=&kt&&int&/span& &span class=&n&&position_x&/span&&span class=&p&&,&/span&&span class=&n&&position_y&/span&&span class=&p&&;&/span& &span class=&c1&&// 飞机位置&/span&
&span class=&kt&&int&/span& &span class=&n&&enemy_x&/span&&span class=&p&&[&/span&&span class=&n&&EnemyNum&/span&&span class=&p&&],&/span&&span class=&n&&enemy_y&/span&&span class=&p&&[&/span&&span class=&n&&EnemyNum&/span&&span class=&p&&];&/span&
&span class=&c1&&// 敌机位置&/span&
&span class=&kt&&int&/span& &span class=&n&&canvas&/span&&span class=&p&&[&/span&&span class=&n&&High&/span&&span class=&p&&][&/span&&span class=&n&&Width&/span&&span class=&p&&]&/span& &span class=&o&&=&/span& &span class=&p&&{&/span&&span class=&mi&&0&/span&&span class=&p&&};&/span& &span class=&c1&&// 二维数组存储游戏画布中对应的元素&/span&
&span class=&c1&&// 0为空格,1为飞机*,2为子弹|,3为敌机@&/span&
&span class=&kt&&int&/span& &span class=&n&&score&/span&&span class=&p&&;&/span& &span class=&c1&&// 得分&/span&
&span class=&kt&&int&/span& &span class=&n&&BulletWidth&/span&&span class=&p&&;&/span& &span class=&c1&&// 子弹宽度&/span&
&span class=&kt&&int&/span& &span class=&n&&EnemyMoveSpeed&/span&&span class=&p&&;&/span& &span class=&c1&&// 敌机移动速度&/span&
&span class=&kt&&void&/span& &span class=&nf&&gotoxy&/span&&span class=&p&&(&/span&&span class=&kt&&int&/span& &span class=&n&&x&/span&&span class=&p&&,&/span&&span class=&kt&&int&/span& &span class=&n&&y&/span&&span class=&p&&)&/span&
&span class=&c1&&//光标移动到(x,y)位置&/span&
&span class=&p&&{&/span&
&span class=&n&&HANDLE&/span& &span class=&n&&handle&/span& &span class=&o&&=&/span& &span class=&n&&GetStdHandle&/span&&span class=&p&&(&/span&&span class=&n&&STD_OUTPUT_HANDLE&/span&&span class=&p&&);&/span&
&span class=&n&&COORD&/span& &span class=&n&&pos&/span&&span class=&p&&;&/span&
&span class=&n&&pos&/span&&span class=&p&&.&/span&&span class=&n&&X&/span& &span class=&o&&=&/span& &span class=&n&&x&/span&&span class=&p&&;&/span&
&span class=&n&&pos&/span&&span class=&p&&.&/span&&span class=&n&&Y&/span& &span class=&o&&=&/span& &span class=&n&&y&/span&&span class=&p&&;&/span&
&span class=&n&&SetConsoleCursorPosition&/span&&span class=&p&&(&/span&&span class=&n&&handle&/span&&span class=&p&&,&/span&&span class=&n&&pos&/span&&span class=&p&&);&/span&
&span class=&p&&}&/span&
&span class=&kt&&void&/span& &span class=&nf&&startup&/span&&span class=&p&&()&/span& &span class=&c1&&// 数据初始化&/span&
&span class=&p&&{&/span&
&span class=&n&&position_x&/span& &span class=&o&&=&/span& &span class=&n&&High&/span&&span class=&o&&-&/span&&span class=&mi&&1&/span&&span class=&p&&;&/span&
&span class=&n&&position_y&/span& &span class=&o&&=&/span& &span class=&n&&Width&/span&&span class=&o&&/&/span&&span class=&mi&&2&/span&&span class=&p&&;&/span&
&span class=&n&&canvas&/span&&span class=&p&&[&/span&&span class=&n&&position_x&/span&&span class=&p&&][&/span&&span class=&n&&position_y&/span&&span class=&p&&]&/span& &span class=&o&&=&/span& &span class=&mi&&1&/span&&span class=&p&&;&/span&
&span class=&kt&&int&/span& &span class=&n&&k&/span&&span class=&p&&;&/span&
&span class=&k&&for&/span& &span class=&p&&(&/span&&span class=&n&&k&/span&&span class=&o&&=&/span&&span class=&mi&&0&/span&&span class=&p&&;&/span&&span class=&n&&k&/span&&span class=&o&&&&/span&&span class=&n&&EnemyNum&/span&&span class=&p&&;&/span&&span class=&n&&k&/span&&span class=&o&&++&/span&&span class=&p&&)&/span&
&span class=&p&&{&/span&
&span class=&n&&enemy_x&/span&&span class=&p&&[&/span&&span class=&n&&k&/span&&span class=&p&&]&/span& &span class=&o&&=&/span& &span class=&n&&rand&/span&&span class=&p&&()&/span&&span class=&o&&%&/span&&span class=&mi&&2&/span&&span class=&p&&;&/span&
&span class=&n&&enemy_y&/span&&span class=&p&&[&/span&&span class=&n&&k&/span&&span class=&p&&]&/span& &span class=&o&&=&/span& &span class=&n&&rand&/span&&span class=&p&&()&/span&&span class=&o&&%&/span&&span class=&n&&Width&/span&&span class=&p&&;&/span&
&span class=&n&&canvas&/span&&span class=&p&&[&/span&&span class=&n&&enemy_x&/span&&span class=&p&&[&/span&&span class=&n&&k&/span&&span class=&p&&]][&/span&&span class=&n&&enemy_y&/span&&span class=&p&&[&/span&&span class=&n&&k&/span&&span class=&p&&]]&/span& &span class=&o&&=&/span& &span class=&mi&&3&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&span class=&n&&score&/span& &span class=&o&&=&/span& &span class=&mi&&0&/span&&span class=&p&&;&/span&
&span class=&n&&BulletWidth&/span& &span class=&o&&=&/span& &span class=&mi&&0&/span&&span class=&p&&;&/span&
&span class=&n&&EnemyMoveSpeed&/span& &span class=&o&&=&/span& &span class=&mi&&20&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&span class=&kt&&void&/span& &span class=&nf&&show&/span&&span class=&p&&()&/span&
&span class=&c1&&// 显示画面&/span&
&span class=&p&&{&/span&
&span class=&n&&gotoxy&/span&&span class=&p&&(&/span&&span class=&mi&&0&/span&&span class=&p&&,&/span&&span class=&mi&&0&/span&&span class=&p&&);&/span&
&span class=&c1&&// 光标移动到原点位置,以下重画清屏&/span&
&span class=&kt&&int&/span& &span class=&n&&i&/span&&span class=&p&&,&/span&&span class=&n&&j&/span&&span class=&p&&;&/span&
&span class=&k&&for&/span& &span class=&p&&(&/span&&span class=&n&&i&/span&&span class=&o&&=&/span&&span class=&mi&&0&/span&&span class=&p&&;&/span&&span class=&n&&i&/span&&span class=&o&&&&/span&&span class=&n&&High&/span&&span class=&p&&;&/span&&span class=&n&&i&/span&&span class=&o&&++&/span&&span class=&p&&)&/span&
&span class=&p&&{&/span&
&span class=&k&&for&/span& &span class=&p&&(&/span&&span class=&n&&j&/span&&span class=&o&&=&/span&&span class=&mi&&0&/span&&span class=&p&&;&/span&&span class=&n&&j&/span&&span class=&o&&&&/span&&span class=&n&&Width&/span&&span class=&p&&;&/span&&span class=&n&&j&/span&&span class=&o&&++&/span&&span class=&p&&)&/span&
&span class=&p&&{&/span&
&span class=&k&&if&/span& &span class=&p&&(&/span&&span class=&n&&canvas&/span&&span class=&p&&[&/span&&span class=&n&&i&/span&&span class=&p&&][&/span&&span class=&n&&j&/span&&span class=&p&&]&/span&&span class=&o&&==&/span&&span class=&mi&&0&/span&&span class=&p&&)&/span&
&span class=&n&&printf&/span&&span class=&p&&(&/span&&span class=&s&&& &&/span&&span class=&p&&);&/span&
&span class=&c1&&//
输出空格&/span&
&span class=&k&&else&/span& &span class=&k&&if&/span& &span class=&p&&(&/span&&span class=&n&&canvas&/span&&span class=&p&&[&/span&&span class=&n&&i&/span&&span class=&p&&][&/span&&span class=&n&&j&/span&&span class=&p&&]&/span&&span class=&o&&==&/span&&span class=&mi&&1&/span&&span class=&p&&)&/span&
&span class=&n&&printf&/span&&span class=&p&&(&/span&&span class=&s&&&*&&/span&&span class=&p&&);&/span&
&span class=&c1&&//
输出飞机*&/span&
&span class=&k&&else&/span& &span class=&k&&if&/span& &span class=&p&&(&/span&&span class=&n&&canvas&/span&&span class=&p&&[&/span&&span class=&n&&i&/span&&span class=&p&&][&/span&&span class=&n&&j&/span&&span class=&p&&]&/span&&span class=&o&&==&/span&&span class=&mi&&2&/span&&span class=&p&&)&/span&
&span class=&n&&printf&/span&&span class=&p&&(&/span&&span class=&s&&&|&&/span&&span class=&p&&);&/span&
&span class=&c1&&//
输出子弹|&/span&
&span class=&k&&else&/span& &span class=&k&&if&/span& &span class=&p&&(&/span&&span class=&n&&canvas&/span&&span class=&p&&[&/span&&span class=&n&&i&/span&&span class=&p&&][&/span&&span class=&n&&j&/span&&span class=&p&&]&/span&&span class=&o&&==&/span&&span class=&mi&&3&/span&&span class=&p&&)&/span&
&span class=&n&&printf&/span&&span class=&p&&(&/span&&span class=&s&&&@&&/span&&span class=&p&&);&/span&
&span class=&c1&&//
输出飞机@&/span&
&span class=&p&&}&/span&
&span class=&n&&printf&/span&&span class=&p&&(&/span&&span class=&s&&&&/span&&span class=&se&&\n&/span&&span class=&s&&&&/span&&span class=&p&&);&/span&
&span class=&p&&}&/span&
&span class=&n&&printf&/span&&span class=&p&&(&/span&&span class=&s&&&得分:%d&/span&&span class=&se&&\n&/span&&span class=&s&&&&/span&&span class=&p&&,&/span&&span class=&n&&score&/span&&span class=&p&&);&/span&
&span class=&n&&Sleep&/span&&span class=&p&&(&/span&&span class=&mi&&20&/span&&span class=&p&&);&/span&
&span class=&p&&}&/span&
&span class=&kt&&void&/span& &span class=&nf&&updateWithoutInput&/span&&span class=&p&&()&/span&
&span class=&c1&&// 与用户输入无关的更新&/span&
&span class=&p&&{&/span&
&span class=&kt&&int&/span& &span class=&n&&i&/span&&span class=&p&&,&/span&&span class=&n&&j&/span&&span class=&p&&,&/span&&span class=&n&&k&/span&&span class=&p&&;&/span&
&span class=&k&&for&/span& &span class=&p&&(&/span&&span class=&n&&i&/span&&span class=&o&&=&/span&&span class=&mi&&0&/span&&span class=&p&&;&/span&&span class=&n&&i&/span&&span class=&o&&&&/span&&span class=&n&&High&/span&&span class=&p&&;&/span&&span class=&n&&i&/span&&span class=&o&&++&/span&&span class=&p&&)&/span&
&span class=&p&&{&/span&
&span class=&k&&for&/span& &span class=&p&&(&/span&&span class=&n&&j&/span&&span class=&o&&=&/span&&span class=&mi&&0&/span&&span class=&p&&;&/span&&span class=&n&&j&/span&&span class=&o&&&&/span&&span class=&n&&Width&/span&&span class=&p&&;&/span&&span class=&n&&j&/span&&span class=&o&&++&/span&&span class=&p&&)&/span&
&span class=&p&&{&/span&
&span class=&k&&if&/span& &span class=&p&&(&/span&&span class=&n&&canvas&/span&&span class=&p&&[&/span&&span class=&n&&i&/span&&span class=&p&&][&/span&&span class=&n&&j&/span&&span class=&p&&]&/span&&span class=&o&&==&/span&&span class=&mi&&2&/span&&span class=&p&&)&/span&
&span class=&p&&{&/span&
&span class=&k&&for&/span& &span class=&p&&(&/span&&span class=&n&&k&/span&&span class=&o&&=&/span&&span class=&mi&&0&/span&&span class=&p&&;&/span&&span class=&n&&k&/span&&span class=&o&&&&/span&&span class=&n&&EnemyNum&/span&&span class=&p&&;&/span&&span class=&n&&k&/span&&span class=&o&&++&/span&&span class=&p&&)&/span&
&span class=&p&&{&/span&
&span class=&k&&if&/span& &span class=&p&&((&/span&&span class=&n&&i&/span&&span class=&o&&==&/span&&span class=&n&&enemy_x&/span&&span class=&p&&[&/span&&span class=&n&&k&/span&&span class=&p&&])&/span& &span class=&o&&&&&/span& &span class=&p&&(&/span&&span class=&n&&j&/span&&span class=&o&&==&/span&&span class=&n&&enemy_y&/span&&span class=&p&&[&/span&&span class=&n&&k&/span&&span class=&p&&]))&/span&
&span class=&c1&&// 子弹击中敌机&/span&
&span class=&p&&{&/span&
&span class=&n&&score&/span&&span class=&o&&++&/span&&span class=&p&&;&/span&
&span class=&c1&&// 分数加1&/span&
&span class=&k&&if&/span& &span class=&p&&(&/span&&span class=&n&&score&/span&&span class=&o&&%&/span&&span class=&mi&&5&/span&&span class=&o&&==&/span&&span class=&mi&&0&/span& &span class=&o&&&&&/span& &span class=&n&&EnemyMoveSpeed&/span&&span class=&o&&&&/span&&span class=&mi&&3&/span&&span class=&p&&)&/span&
&span class=&c1&&// 达到一定积分后,敌机变快&/span&
&span class=&n&&EnemyMoveSpeed&/span&&span class=&o&&--&/span&&span class=&p&&;&/span&
&span class=&k&&if&/span& &span class=&p&&(&/span&&span class=&n&&score&/span&&span class=&o&&%&/span&&span class=&mi&&5&/span&&span class=&o&&==&/span&&span class=&mi&&0&/span&&span class=&p&&)&/span&
&span class=&c1&&// 达到一定积分后,子弹变厉害&/span&
&span class=&n&&BulletWidth&/span&&span class=&o&&++&/span&&span class=&p&&;&/span&
&span class=&n&&canvas&/span&&span class=&p&&[&/span&&span class=&n&&enemy_x&/span&&span class=&p&&[&/span&&span class=&n&&k&/span&&span class=&p&&]][&/span&&span class=&n&&enemy_y&/span&&span class=&p&&[&/span&&span class=&n&&k&/span&&span class=&p&&]]&/span& &span class=&o&&=&/span& &span class=&mi&&0&/span&&span class=&p&&;&/span&
&span class=&n&&enemy_x&/span&&span class=&p&&[&/span&&span class=&n&&k&/span&&span class=&p&&]&/span& &span class=&o&&=&/span& &span class=&n&&rand&/span&&span class=&p&&()&/span&&span class=&o&&%&/span&&span class=&mi&&2&/span&&span class=&p&&;&/span&
&span class=&c1&&// 产生新的飞机&/span&
&span class=&n&&enemy_y&/span&&span class=&p&&[&/span&&span class=&n&&k&/span&&span class=&p&&]&/span& &span class=&o&&=&/span& &span class=&n&&rand&/span&&span class=&p&&()&/span&&span class=&o&&%&/span&&span class=&n&&Width&/span&&span class=&p&&;&/span&
&span class=&n&&canvas&/span&&span class=&p&&[&/span&&span class=&n&&enemy_x&/span&&span class=&p&&[&/span&&span class=&n&&k&/span&&span class=&p&&]][&/span&&span class=&n&&enemy_y&/span&&span class=&p&&[&/span&&span class=&n&&k&/span&&span class=&p&&]]&/span& &span class=&o&&=&/span& &span class=&mi&&3&/span&&span class=&p&&;&/span&
&span class=&n&&canvas&/span&&span class=&p&&[&/span&&span class=&n&&i&/span&&span class=&p&&][&/span&&span class=&n&&j&/span&&span class=&p&&]&/span& &span class=&o&&=&/span& &span class=&mi&&0&/span&&span class=&p&&;&/span&
&span class=&c1&&// 子弹消失&/span&
&span class=&p&&}&/span&
&span class=&p&&}&/span&
&span class=&c1&&// 子弹向上移动&/span&
&span class=&n&&canvas&/span&&span class=&p&&[&/span&&span class=&n&&i&/span&&span class=&p&&][&/span&&span class=&n&&j&/span&&span class=&p&&]&/span& &span class=&o&&=&/span& &span class=&mi&&0&/span&&span class=&p&&;&/span&
&span class=&k&&if&/span& &span class=&p&&(&/span&&span class=&n&&i&/span&&span class=&o&&&&/span&&span class=&mi&&0&/span&&span class=&p&&)&/span&
&span class=&n&&canvas&/span&&span class=&p&&[&/span&&span class=&n&&i&/span&&span class=&o&&-&/span&&span class=&mi&&1&/span&&span class=&p&&][&/span&&span class=&n&&j&/span&&span class=&p&&]&/span& &span class=&o&&=&/span& &span class=&mi&&2&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&span class=&p&&}&/span&
&span class=&p&&}&/span&
&span class=&k&&static&/span& &span class=&kt&&int&/span& &span class=&n&&speed&/span& &span class=&o&&=&/span& &span class=&mi&&0&/span&&span class=&p&&;&/span&
&span class=&k&&if&/span& &span class=&p&&(&/span&&span class=&n&&speed&/span&&span class=&o&&&&/span&&span class=&n&&EnemyMoveSpeed&/span&&span class=&p&&)&/span&
&span class=&n&&speed&/span&&span class=&o&&++&/span&&span class=&p&&;&/span&
&span class=&k&&for&/span& &span class=&p&&(&/span&&span class=&n&&k&/span&&span class=&o&&=&/span&&span class=&mi&&0&/span&&span class=&p&&;&/span&&span class=&n&&k&/span&&span class=&o&&&&/span&&span class=&n&&EnemyNum&/span&&span class=&p&&;&/span&&span class=&n&&k&/span&&span class=&o&&++&/span&&span class=&p&&)&/

我要回帖

更多关于 16能设计什么图案 的文章

 

随机推荐