Forum Replies Created
-
AuthorPosts
-
::
According to the index operator of std::array, it makes sense.
The const reference guarantees that it cannot be modified, and constexpr that I can potentially be executed at compile time.
C++23 supports the multidimensional subscript operator:
#include <array> #include <iostream> template<typename T, std::size_t X, std::size_t Y> struct Matrix { std::array<T, X * Y> mat{}; T& operator[](std::size_t x, std::size_t y) { return mat[y * X + x]; } }; int main() { std::cout << '\n'; Matrix<int, 3, 3> mat; for (auto i : {0, 1, 2}) { for (auto j : {0, 1, 2}) mat[i, j] = (i * 3) + j; } for (auto i : {0, 1, 2}) { for (auto j : {0, 1, 2}) std::cout << mat[i, j] << " "; } std::cout << '\n'; }
::With C++20, I would strongly suggest std::atomic_flag. Before, you must use std::condition_variable. For one-time synchronization in C++11, you can also use a future/promise pair. std::condition_variable is the slowest and most complicated variant. The post “Performance Comparison of Condition Variables and Atomics in C++20” will give you the first numbers on Windows.
When you don’t break the memory order sequential consistency, atomics behave pretty natural. On X86, there is no reason for breaking the strong memory order sequential consistency.
::Very good. The program has a memory leak. Window should have a virtual destructor.
This is how the program behaves: https://godbolt.org/z/rzY4bMvr5
This is how the program should behave: https://godbolt.org/z/T3xsaebcf
::A spinlock may be useful when you only wait for a short period of time because the sleeping of the mutex is expensive. Usually, a mutex spins for a short time and then falls asleep. std::mutex is only a wrapper around the OS mutex. This means it is probably a pthread mutex on Unix/Linux. You can access the underlying mutex by calling std::mutex::native_handle.
25. January 2024 at 18:09 in reply to: Fetch multiply implementation in Meeting C++ presentation #632951::Here is your modified await_suspend call.
void await_suspend(std::coroutine_handle<> h) { auto outerThread = std::jthread([h]() { h.resume();}); }
You use a jthread. The jthread automatically joins in its destructor if still joinable. This means, your await_suspend call is blocking.
Additionally, you don’t have a handle to the thread. You can, for example, not cooperatively interrupt it.
::The function await_suspend handles the suspension of the coroutine. await_suspend is the crucial function of the Awaiter. It can have the following return types:
- void: the control flow immediately returns to the caller. The coroutine remains suspended.
- bool:
- true: the control flow immediately returns to the caller
- false: the coroutine is resumed
- std::coroutine_handle<>:
- if it returns a coroutine handle coroHandle of another coroutine, this coroutine is resumed: coroHandle.resume(). This strategy is called symmetric transfer.
- std::noop_coroutine: no coroutine is resumed. Equivalent to returning true.
In both the example and in the case where we don’t call handle.resume() in await_suspend like here the coroutines get destroyed thanks to the destructor of Job and there are no leaks right?
Right.
In the example, I think it would be better to use the name MySuspendSometimes instead of MySuspendAlways.
You are right. It only sometimes suspends when await_ready return true.
::- When I have three iterations in the coroutine and four iterations in main, I get the last value repeated and no error
You resume final_suspend. This is undefined behavior.
- When I have two iterations in the coroutine and four iterations in main, I get an error
There is nothing left to resume. The coroutine already ended.
::There is an excellent about distributing modules on CppCon 2023: C++20 Modules: The Packaging and Binary Redistribution Story by Luis Caro Campos
-
AuthorPosts