co_await 在 std::experimental::generator 类型的协程中不受支持
co_await is not supported in coroutines of type std::experimental::generator
我应该定义什么魔法生成器才能使下面的代码工作?
#include <experimental/generator>
std::experimental::generator<int> generateInts()
{
for (int i = 0; i < 10; ++i)
{
co_await some_async_func();
co_yield i;
}
};
使用 MSVC 我得到编译器错误:
error C2338: co_await is not supported in coroutines of type std::experimental::generator
编辑 1:
错误来自其 await_transform
:
template <class _Uty>
_Uty&& await_transform(_Uty&& _Whatever) {
static_assert(_Always_false<_Uty>,
"co_await is not supported in coroutines of type std::experimental::generator");
return _STD forward<_Uty>(_Whatever);
}
任何 experimental
文件夹中的内容 不是 C++20 的一部分。在这种情况下,这似乎是 co_await
的协程 TS 版本的某些内容的一部分。但是,该功能在标准化过程中经历了 很多 的更改。因此,微软通过给你一个非常具体和信息丰富的错误来给你一个头's-up:你不能将 C++20 特性与该头文件中的类型一起使用(或者可能是任何其他“实验性”头文件) .
您必须编写自己的生成器类型或使用其他与 C++20 协程兼容的生成器类型。
我的理解大概是generator_iterator
无法处理co_await
,因为它需要用co_yeld
暂停任务,看iterator源码:
generator_iterator& operator++()
{
m_coroutine.resume();
if (m_coroutine.done())
{
m_coroutine.promise().rethrow_if_exception();
}
return *this;
}
可能某些 async_generator
应该处理任务被 co_await
挂起并且 return 值尚未准备好时的情况,因此它的 operator++
也会挂起轮到它变得像这样异步:
async_generator_increment_operation<T> operator++() noexcept
{
return async_generator_increment_operation<T>{ *this };
}
其中async_generator_increment_operation
定义如下:
template<typename T>
class async_generator_increment_operation final : public async_generator_advance_operation
{
public:
async_generator_increment_operation(async_generator_iterator<T>& iterator) noexcept
: async_generator_advance_operation(iterator.m_coroutine.promise(), iterator.m_coroutine)
, m_iterator(iterator)
{}
async_generator_iterator<T>& await_resume();
private:
async_generator_iterator<T>& m_iterator;
};
template<typename T>
async_generator_iterator<T>& async_generator_increment_operation<T>::await_resume()
{
if (m_promise->finished())
{
// Update iterator to end()
m_iterator = async_generator_iterator<T>{ nullptr };
m_promise->rethrow_if_unhandled_exception();
}
return m_iterator;
}
我应该定义什么魔法生成器才能使下面的代码工作?
#include <experimental/generator>
std::experimental::generator<int> generateInts()
{
for (int i = 0; i < 10; ++i)
{
co_await some_async_func();
co_yield i;
}
};
使用 MSVC 我得到编译器错误:
error C2338: co_await is not supported in coroutines of type std::experimental::generator
编辑 1:
错误来自其 await_transform
:
template <class _Uty>
_Uty&& await_transform(_Uty&& _Whatever) {
static_assert(_Always_false<_Uty>,
"co_await is not supported in coroutines of type std::experimental::generator");
return _STD forward<_Uty>(_Whatever);
}
任何 experimental
文件夹中的内容 不是 C++20 的一部分。在这种情况下,这似乎是 co_await
的协程 TS 版本的某些内容的一部分。但是,该功能在标准化过程中经历了 很多 的更改。因此,微软通过给你一个非常具体和信息丰富的错误来给你一个头's-up:你不能将 C++20 特性与该头文件中的类型一起使用(或者可能是任何其他“实验性”头文件) .
您必须编写自己的生成器类型或使用其他与 C++20 协程兼容的生成器类型。
我的理解大概是generator_iterator
无法处理co_await
,因为它需要用co_yeld
暂停任务,看iterator源码:
generator_iterator& operator++()
{
m_coroutine.resume();
if (m_coroutine.done())
{
m_coroutine.promise().rethrow_if_exception();
}
return *this;
}
可能某些 async_generator
应该处理任务被 co_await
挂起并且 return 值尚未准备好时的情况,因此它的 operator++
也会挂起轮到它变得像这样异步:
async_generator_increment_operation<T> operator++() noexcept
{
return async_generator_increment_operation<T>{ *this };
}
其中async_generator_increment_operation
定义如下:
template<typename T>
class async_generator_increment_operation final : public async_generator_advance_operation
{
public:
async_generator_increment_operation(async_generator_iterator<T>& iterator) noexcept
: async_generator_advance_operation(iterator.m_coroutine.promise(), iterator.m_coroutine)
, m_iterator(iterator)
{}
async_generator_iterator<T>& await_resume();
private:
async_generator_iterator<T>& m_iterator;
};
template<typename T>
async_generator_iterator<T>& async_generator_increment_operation<T>::await_resume()
{
if (m_promise->finished())
{
// Update iterator to end()
m_iterator = async_generator_iterator<T>{ nullptr };
m_promise->rethrow_if_unhandled_exception();
}
return m_iterator;
}