MSVCはC++20でもジェネレーターが使えるようにexperimental機能としてstd::experimental::generator<T>
を提供しています。このクラスを使うとco_yield
で簡単にジェネレーターを実装できますが、範囲for文と組み合わせる場合は参照で受け取った方が良さそうです。参照で受け取らない場合、デストラクタが繰り返し呼び出されました。
// C++20 // プロジェクトプロパティ→C/C++→コマンドライン→追加のオプションに「/await」を追加してください。 #include <iostream> #include <experimental/generator> #include <ranges> class coroutine_test { public: coroutine_test() { std::wcout << L"coroutine_test()" << std::endl; } ~coroutine_test() { std::wcout << L"~coroutine_test()" << std::endl; } }; std::experimental::generator<coroutine_test> f() { auto co = coroutine_test(); co_yield co; co_yield co; co_yield co; co_yield co; co_yield co; } int main() { // 参照で受け取る for (auto& co : f() | std::views::take(3)) { std::wcout << L"for" << std::endl; } // coroutine_test() // for // for // for // ~coroutine_test() std::wcout << std::endl; // 参照で受け取らない for (auto co : f() | std::views::take(3)) { std::wcout << L"for" << std::endl; } // coroutine_test() // for // ~coroutine_test() // for // ~coroutine_test() // for // ~coroutine_test() // ~coroutine_test() return 0; }