Я пытаюсь определить свой собственный тип обещания сопрограммы, и у меня есть следующие объявления:
void return_void() requires std::same_as {}
template
void return_value(X&& x) requires (!std::same_as) {}
Но компилятор жалуется, что я определил оба, несмотря на объявления require:
return.cpp: In function ‘Future b()’:
return.cpp:103:40: error: the coroutine promise type ‘std::__n4861::__coroutine_traits_impl::promise_type’ {aka ‘Future::promise_type’} declares both ‘return_value’ and ‘return_void’
103 | __attribute__((noinline)) Future b()
| ^
return.cpp:27:14: note: ‘return_void’ declared here
27 | void return_void() requires std::same_as {}
| ^~~~~~~~~~~
return.cpp:30:14: note: ‘return_value’ first declared here
30 | void return_value(X&& x) requires (!std::same_as) {}
| ^~~~~~~~~~~~
Разве смысл функции require не в том, чтобы иметь возможность выражать подобные перегрузки без трюков std::enable_if и выведенных типов?
Полный минимальный пример:
#include
#include
#include
#include
#include
template
class Future
{
public:
class Awaiter;
class promise_type {
private:
std::exception_ptr _exception;
std::coroutine_handle _continuation;
friend class Awaiter;
public:
Future get_return_object() { return {HandleT::from_promise(*this)}; }
std::suspend_always initial_suspend() { return {}; }
std::suspend_never final_suspend() noexcept { return {}; }
void return_void() requires std::same_as {}
template
void return_value(X&& x) requires (!std::same_as) {}
void unhandled_exception() {
_exception = std::current_exception();
}
};
operator bool() const
{
return _status == Status::Done || _status == Status::Exception;
}
struct Awaiter {
private:
Future& future;
public:
explicit Awaiter(Future& future)
: future(future)
{}
// this will check if the future is already done, e.g. if it
// was `co_await`ed previously
bool await_ready() const noexcept { return bool(future); }
// this coroutine is the one doing the `co_await`
std::coroutine_handle await_suspend(std::coroutine_handle handle) noexcept
{
// remember we want to resume back intot his caller later
future._handle.promise()._continuation = handle;
// For now let the coroutine associated with this future
// run, via "symmetric transfer", which takes the caller
// resume call off the stack and replaces it with this
// coroutine.
return future._handle;
}
void await_resume() const noexcept
{
}
};
auto operator co_await() {
return Awaiter(*this);
}
void resume() {
_handle.resume();
}
protected:
using HandleT = std::coroutine_handle;
Future(HandleT&& p)
: _handle(std::move(p))
{}
Future(const Future&) = delete;
Future& operator=(const Future&) = delete;
friend class Awaiter;
enum class Status {
Unfinished,
Done,
Exception,
Empty
} _status = Status::Unfinished;
HandleT _handle;
std::exception_ptr _exception = nullptr;
};
Future b()
{
co_return;
}
Подробнее здесь: https://stackoverflow.com/questions/793 ... -exclusive
Почему C++ не может сказать, что return_void и return_value являются взаимоисключающими? ⇐ C++
Программы на C++. Форум разработчиков
1735996382
Anonymous
Я пытаюсь определить свой собственный тип обещания сопрограммы, и у меня есть следующие объявления:
void return_void() requires std::same_as {}
template
void return_value(X&& x) requires (!std::same_as) {}
Но компилятор жалуется, что я определил оба, несмотря на объявления require:
return.cpp: In function ‘Future b()’:
return.cpp:103:40: error: the coroutine promise type ‘std::__n4861::__coroutine_traits_impl::promise_type’ {aka ‘Future::promise_type’} declares both ‘return_value’ and ‘return_void’
103 | __attribute__((noinline)) Future b()
| ^
return.cpp:27:14: note: ‘return_void’ declared here
27 | void return_void() requires std::same_as {}
| ^~~~~~~~~~~
return.cpp:30:14: note: ‘return_value’ first declared here
30 | void return_value(X&& x) requires (!std::same_as) {}
| ^~~~~~~~~~~~
Разве смысл функции require не в том, чтобы иметь возможность выражать подобные перегрузки без трюков std::enable_if и выведенных типов?
Полный минимальный пример:
#include
#include
#include
#include
#include
template
class Future
{
public:
class Awaiter;
class promise_type {
private:
std::exception_ptr _exception;
std::coroutine_handle _continuation;
friend class Awaiter;
public:
Future get_return_object() { return {HandleT::from_promise(*this)}; }
std::suspend_always initial_suspend() { return {}; }
std::suspend_never final_suspend() noexcept { return {}; }
void return_void() requires std::same_as {}
template
void return_value(X&& x) requires (!std::same_as) {}
void unhandled_exception() {
_exception = std::current_exception();
}
};
operator bool() const
{
return _status == Status::Done || _status == Status::Exception;
}
struct Awaiter {
private:
Future& future;
public:
explicit Awaiter(Future& future)
: future(future)
{}
// this will check if the future is already done, e.g. if it
// was `co_await`ed previously
bool await_ready() const noexcept { return bool(future); }
// this coroutine is the one doing the `co_await`
std::coroutine_handle await_suspend(std::coroutine_handle handle) noexcept
{
// remember we want to resume back intot his caller later
future._handle.promise()._continuation = handle;
// For now let the coroutine associated with this future
// run, via "symmetric transfer", which takes the caller
// resume call off the stack and replaces it with this
// coroutine.
return future._handle;
}
void await_resume() const noexcept
{
}
};
auto operator co_await() {
return Awaiter(*this);
}
void resume() {
_handle.resume();
}
protected:
using HandleT = std::coroutine_handle;
Future(HandleT&& p)
: _handle(std::move(p))
{}
Future(const Future&) = delete;
Future& operator=(const Future&) = delete;
friend class Awaiter;
enum class Status {
Unfinished,
Done,
Exception,
Empty
} _status = Status::Unfinished;
HandleT _handle;
std::exception_ptr _exception = nullptr;
};
Future b()
{
co_return;
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79327739/why-cant-c-tell-return-void-and-return-value-are-mutually-exclusive[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия