You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无需返回值时co_return该返回什么?concurrencpp库实现疑问

问题描述

我在自己的库concurrencpp中想要实现make_exceptional_lazy_result函数,功能和C#的Task.FromException方法一致——这个函数会始终抛出异常,永远不会通过co_return返回有效对象。

当前的实现代码如下:

template<class type, class exception_type>
lazy_result<type> make_exceptional_lazy_result(exception_type exception) {
    throw exception;
    co_return *static_cast<type*>(std::malloc(sizeof(type)));
}

我对这种用malloc的取巧写法很不舒服:一方面必须写co_return语句,另一方面程序永远不会执行到这一行。我想知道有没有更好的实现方式?另外我担心返回未初始化本地内存的引用是否符合C++语言规范,而且type不一定支持默认构造,没法直接返回type{}。

优化方案

1. 使用std::declval配合强制转换

利用std::declval生成type类型的纯右值,通过强制转换绕开实际构造需求——由于这行代码永远不会被执行,不会触发对象构造,完全符合语言规范:

template<class type, class exception_type>
lazy_result<type> make_exceptional_lazy_result(exception_type exception) {
    throw exception;
    co_return static_cast<type&&>(std::declval<type>());
}

std::declval仅用于编译期类型推导,不会生成实际代码,完美适配type无默认构造的场景。

2. 自定义协程Promise逻辑(最优底层方案)

如果lazy_result是你自定义的协程类型,可以直接在Promise类中添加创建异常结果的接口,跳过协程体执行:

template<class type, class exception_type>
lazy_result<type> make_exceptional_lazy_result(exception_type exception) {
    auto promise = std::make_unique<typename lazy_result<type>::promise_type>();
    promise->set_exception(std::make_exception_ptr(exception));
    return lazy_result<type>(promise->get_return_object());
}

这种方式完全避免冗余的co_return语句,从协程机制根源处理异常结果创建,性能和规范性都最优。

3. 用co_yield占位(仅当lazy_result支持时)

如果lazy_result的协程允许co_yield,可以用它来满足语法要求,不过实用性不如前两种:

template<class type, class exception_type>
lazy_result<type> make_exceptional_lazy_result(exception_type exception) {
    throw exception;
    co_yield std::declval<type>();
    co_return std::declval<type>();
}

原写法的问题说明

你之前用malloc的写法存在合规性问题:std::malloc分配的内存未初始化,解引用后是未构造的对象,即便代码不会执行到这里,也不符合C++对象模型要求——未构造的对象不能被当作有效对象返回,编译器静态分析也可能报错。

内容的提问来源于stack exchange,提问作者David Haim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 04:25:18