从reddit/hackernews/lobsters/meetingcpp摘抄一些c++动态。
每周更新
周刊项目地址 github,在线地址 | discord讨论群组 |飞书讨论群组|知乎专栏 |
---|
欢迎投稿,推荐或自荐文章/软件/资源等,请提交 issue
作者描述了一个move对象,但对象没有实现好拷贝函数和移动函数导致UB的场景。在 -stdlib=libc++的某些场景下的复制可能出现问题。我测试了没复现出来
使用整数上的注意事项,讲了很多,包括整数提升相关的细节
这里列出笔者比较感兴趣的
Raymond写文章非常多 水 这个就是介绍一个promise type的封装。他也写了很多coroutine文章。写的很琐碎,后面一系列文章都是围绕这个封装做组件库。就不多介绍了
如果真的想用库,用这个 https://github.com/lewissbaker/cppcoro
观点没什么意思,就是照搬 https://github.com/mtrebi/memory-allocators的readme,值得看看
简单来说,内存分配器要有自己的定义和选型,比如应用的数据是可以预估的proxy,数据失效快,那就可以分配一个大数组,固定块,来分配,在程序一开始就分配好,之后就不用malloc,全部placement new就可以
如果是比较琐碎的数据类型,变化比较多,那还是jemalloc这种更合适一些
看这段代码,演示在这里https://godbolt.org/z/jEGK1z3nT
class iapi {
public:
virtual ~iapi() = default;
virtual auto call() const -> int = 0;
};
template<class T>
concept api = requires(const T& t) {
{ t.call() } -> std::same_as<int>;
};
template<class T1 = class iapi, // NOTE: class iapi for template injection
api T2 = class iapi> // NOTE: class iapi for concepts injection
struct app {
constexpr app(const T1& t1, const T2& t2, const iapi& t3) { // NOTE: iapi for interface injection
assert(42 == t1.call() and 42 == t2.call() and 42 == t3.call());
}
};
int main() {
struct fake_api : iapi {
auto call() const -> int { return 42; }
};
const auto injector = boost::di::make_injector(
boost::di::bind<iapi>.to<fake_api>() // bind iapi to fake_api
);
boost::di::create<app>(injector); // return an app
}
还是生成器,co_yield需要实现promise_type的五个函数,就行了,不用实现awaitable
看代码
#include <coroutine>
#include <memory>
#include <iostream>
#include <string>
#include <vector>
template<typename T>
struct Generator {
struct promise_type;
using handle_type = std::coroutine_handle<promise_type>;
Generator(handle_type h): coro(h) {}
handle_type coro;
~Generator() {
if ( coro ) coro.destroy();
}
Generator(const Generator&) = delete;
Generator& operator = (const Generator&) = delete;
Generator(Generator&& oth): coro(oth.coro) {
oth.coro = nullptr;
}
Generator& operator = (Generator&& oth) {
coro = oth.coro;
oth.coro = nullptr;
return *this;
}
T getNextValue() {
coro.resume();
return coro.promise().current_value;
}
struct promise_type {
promise_type() {}
~promise_type() {}
std::suspend_always initial_suspend() {
return {};
}
std::suspend_always final_suspend() noexcept {
return {};
}
auto get_return_object() {
return Generator{handle_type::from_promise(*this)};
}
// co_yeilds
std::suspend_always yield_value(const T value) {
current_value = value;
return {};
}
void return_void() {}
void unhandled_exception() {
std::exit(1);
}
T current_value;
};
};
template <typename Cont>
Generator<typename Cont::value_type> getNext(Cont cont) {
for (auto c: cont) co_yield c;
}
int main() {
std::cout << '\n';
std::string helloWorld = "Hello world";
auto gen = getNext(helloWorld); // (1)
for (int i = 0; i < helloWorld.size(); ++i) {
std::cout << gen.getNextValue() << " "; // (4)
}
std::cout << "\n\n";
auto gen2 = getNext(helloWorld); // (2)
for (int i = 0; i < 5 ; ++i) { // (5)
std::cout << gen2.getNextValue() << " ";
}
std::cout << "\n\n";
std::vector myVec{1, 2, 3, 4 ,5};
auto gen3 = getNext(myVec); // (3)
for (int i = 0; i < myVec.size() ; ++i) { // (6)
std::cout << gen3.getNextValue() << " ";
}
std::cout << '\n';
}
编译器会把coroutine改成两个流程 promise流程和awaitable流程
promise
{
Promise prom;
co_await prom.initial_suspend();
try {
<function body having co_return, co_yield, or co_wait>
}
catch (...) {
prom.unhandled_exception();
}
FinalSuspend:
co_await prom.final_suspend();
}
awaitable
awaitable.await_ready() returns false:
suspend coroutine
awaitable.await_suspend(coroutineHandle) returns:
void:
awaitable.await_suspend(coroutineHandle);
coroutine keeps suspended
return to caller
bool:
bool result = awaitable.await_suspend(coroutineHandle);
if result:
coroutine keep suspended
return to caller
else:
go to resumptionPoint
another coroutine handle:
auto anotherCoroutineHandle = awaitable.await_suspend(coroutineHandle);
anotherCoroutineHandle.resume();
return to caller
resumptionPoint:
return awaitable.await_resume();
对于基本类型的转换,不要用reinterpret_cast了!用bit_cast!gcc trunk分支已经支持了,可以在godbolt上玩一玩
window平台抓崩溃信息的一个总结回顾
看到这里或许你有建议或者疑问或者指出错误,请留言评论! 多谢! 你的评论非常重要!也可以帮忙点赞收藏转发!多谢支持!
This site is open source. [Improve this page](https://github.com/wanghenshui/cppweeklynews/edit/dev/posts/006.md).