公众号
qq群 手机qq点击进入
RSS https://github.com/wanghenshui/cppweeklynews/releases.atom
欢迎投稿,推荐或自荐文章/软件/资源等
最近在找工作准备面试题,更新可能有些拖沓,见谅
本周内容比较少
本期文章由 Amnesia Captain 黄亮 Anein Jerry 赞助
标准委员会动态/ide/编译器信息放在这里
编译器信息最新动态推荐关注hellogcc公众号 OSDT Weekly 2023-11-22 第229期
boost 有个scope库正在评审中 https://lastique.github.io/scope/libs/scope/doc/html/scope/scope_guards.html
简单来说又是个scope guard
还是coroutine介绍。懂得可以跳过了
// simpleCoroutine.cpp
#include <coroutine>
#include <iostream>
struct MyCoroutine { // (1)
struct promise_type {
MyCoroutine get_return_object() {
return std::coroutine_handle<promise_type>::from_promise(*this);
}
std::suspend_always initial_suspend() {
return {};
}
std::suspend_always final_suspend() noexcept {
return {};
}
void return_void() {}
void unhandled_exception() {}
};
MyCoroutine(std::coroutine_handle<promise_type> handle): handle{handle} {}
void resume() {
handle.resume();
}
void destroy() {
handle.destroy();
}
std::coroutine_handle<promise_type> handle;
};
MyCoroutine simpleCoroutine() { // (2)
std::cout << "Start coroutine\n";
co_await std::suspend_always{};
std::cout << "Resume coroutine\n";
}
int main() {
MyCoroutine coro = simpleCoroutine();
std::cout << "Coroutine is not executed yet\n";
coro.resume();
std::cout << "Suspend coroutine\n";
coro.resume();
coro.destroy();
return 0;
}
实际上是这样的
MyCoroutine simpleCoroutine() {
MyCoroutine::promise_type p();
MyCoroutine coro_obj = p.get_return_object();
try {
co_await p.inital_suspend();
std::cout << "Start coroutine\n";
co_await std::suspend_always{};
std::cout << "Resume coroutine\n";
} catch(...) {
p.unhandled_exception();
}
co_await p.final_suspend();
}
理解Awaitable,suspend_always就是内建的一个简单awaitable
struct suspend_always {
constexpr bool await_ready() const noexcept { return false; }
constexpr void await_suspend(coroutine_handle<>) const noexcept {}
constexpr void await_resume() const noexcept {}
};
co_await suspend_always 相当于
auto&& awaiter = std::suspend_always{};
if(!awaiter.await_ready()) {
awaiter.await_suspend(std::coroutine_handle<>...);
//<suspend/resume>
}
awaiter.await_resume();
这样最重要的co_await功能大概你就明白了
好了,来点复杂的
#include <coroutine>
#include <iostream>
#include <queue>
struct Task {
struct promise_type {
std::suspend_always initial_suspend() noexcept { return {}; }
std::suspend_always final_suspend() noexcept { return {}; }
Task get_return_object() {
return std::coroutine_handle<promise_type>::from_promise(*this);
}
void return_void() {}
void unhandled_exception() {}
};
Task(std::coroutine_handle<promise_type> handle): handle{handle} {}
auto get_handle() { return handle; }
std::coroutine_handle<promise_type> handle;
};
class Scheduler {
std::queue<std::coroutine_handle<>> _tasks;
public:
void emplace(std::coroutine_handle<> task) {
_tasks.push(task);
}
void schedule() {
while(!_tasks.empty()) {
auto task = _tasks.front();
_tasks.pop();
task.resume();
if(!task.done()) {
_tasks.push(task);
}
else {
task.destroy();
}
}
}
auto suspend() {
return std::suspend_always{};
}
};
Task TaskA(Scheduler& sch) {
std::cout << "Hello from TaskA\n";
co_await sch.suspend();
std::cout << "Executing the TaskA\n";
co_await sch.suspend();
std::cout << "TaskA is finished\n";
}
Task TaskB(Scheduler& sch) {
std::cout << "Hello from TaskB\n";
co_await sch.suspend();
std::cout << "Executing the TaskB\n";
co_await sch.suspend();
std::cout << "TaskB is finished\n";
}
int main() {
std::cout << '\n';
Scheduler sch;
sch.emplace(TaskA(sch).get_handle());
sch.emplace(TaskB(sch).get_handle());
std::cout << "Start scheduling...\n";
sch.schedule();
std::cout << '\n';
}
可以了。你已经入门了。 接下来可以看seastar代码了
或者先看这个 https://github.com/andreasbuhr/cppcoro
简单玩法
struct Color {
uint8_t r{ 0 };
uint8_t g{ 0 };
uint8_t b{ 0 };
};
template <>
struct std::formatter<Color> {
constexpr auto parse(std::format_parse_context& ctx) {
return ctx.begin();
}
auto format(const Color& col, std::format_context& ctx) const {
return std::format_to(ctx.out(), "({}, {}, {})", col.r, col.g, col.b);
}
};
恐怖玩法
template <>
struct std::formatter<Color> : std::formatter<string_view> {
auto format(const Color& col, std::format_context& ctx) const {
std::string temp;
std::format_to(std::back_inserter(temp), "({}, {}, {})",
col.r, col.g, col.b);
return std::formatter<string_view>::format(temp, ctx);
}
};
满头大汗玩法
template <>
struct std::formatter<Color> {
constexpr auto parse(std::format_parse_context& ctx){
auto pos = ctx.begin();
while (pos != ctx.end() && *pos != '}') {
if (*pos == 'h' || *pos == 'H')
isHex_ = true;
++pos;
}
return pos; // expect `}` at this position, otherwise,
// it's error! exception!
}
auto format(const Color& col, std::format_context& ctx) const {
if (isHex_) {
uint32_t val = col.r << 16 | col.g << 8 | col.b;
return std::format_to(ctx.out(), "#{:x}", val);
}
return std::format_to(ctx.out(), "({}, {}, {})", col.r, col.g, col.b);
}
bool isHex_{ false };
};
// std::cout << std::format("col {}\n", Color{ 100, 200, 255 });
// std::cout << std::format("col {:h}\n", Color{ 100, 200, 255 });
// col (100, 200, 255)
// col #64c8ff
c++和编译器结合太深了。但有些知识并不是都知道,导致错误触发未定义行为
这个基本上是去年cppcon的总结,挺好的。值得看看
这个pfr magic_get希望大家都掌握。起码嘴了十几次了
patchelf实践还是比较少见的。挺有意思
#include <iostream>
#include <string>
struct S {
int m_num;
std::string m_text;
};
int main() {
S s{42};
std::cout << "s.m_num: " << s.m_num << ", s.m_text: " << s.m_text << '\n';
}
这种构造有字段没初始化,加告警-Wmissing-field-initializers
最近进展,发现 cmpxchg16b 不该用。竟然比mutex还慢,还在研究
Unilang deepin的一个通用编程语言,点子有点意思,也缺人,感兴趣的可以github讨论区或者deepin论坛看一看。这里也挂着长期推荐了
https://gitee.com/okstar-org/ok-edu-desktop 一个IM通信软件,做IM的可以关注,现在正在做全面整合阶段,开始组建商业团队阶段,年底开始融资,你参加了就快发财了,会的快来
https://github.com/sharkdp/minicpp 基于inotify的一个repl c++环境
简单说就是你的文件更改了 触发inotify 然后 回调一下make
这可比cling简单多了
又一个embed库。std::embed还没影呢,凑活用的东西
感觉很快,但没有和sonic-cpp的对比。我本来想比一下
我折腾了半天sonic-cpp编译。ubuntu 2204 zen4. 各种编不过。放弃了我靠
跑了glaze自带的压测
比yyjson快。性能不错,和simdjson也有一拼。另外就是还用上了最新反射技术。实践挺深的
数据贴这里,感兴趣的自己看吧
无锡编译期HPC AI创业 需要会LLVM gcc的 https://mp.weixin.qq.com/s/qkwjICB_fzzMJErXmbKBBw
哎,再也不喝冰美式。一宿没睡着我靠
之前收集了一波读者投票,关于周更其余实践插一些别的内容
重点在代码介绍代码走读。这里搞点素材给大家逼逼两句。类似lighting talk,5页10页ppt
另外也收集收集大家的其他意见以及投稿。能投稿广告收益都给你。咱们公众号每篇文章稳定收益7块,加个鸡腿没啥问题
本周内容不多啊,还是希望大家多多互动