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

如何解决BOOST_OUTCOME_TRY适配llvm::ErrorOr<T>的编译错误?

问题分析与解决方法

编译失败的核心原因

  1. 函数名不匹配:Boost Outcome要求的失败分支处理函数是try_operation_return_as,但你定义的是try_return_as(缺少operation_前缀),导致宏扩展时找不到对应函数。
  2. 错误的错误访问方式:你在try_return_as中使用v->getError(),但v->仅在ErrorOr有值时有效,失败时应该调用v.getError()来获取错误对象,否则会触发未定义行为。
  3. 模板范围过窄:你的模板仅针对llvm::ErrorOr<std::unique_ptr<T>>,无法复用给其他ErrorOr类型,且函数实现存在路径无返回值的问题(当v有值时,函数没有返回值,违反C++语法)。

修正后的代码实现

#include <llvm/Support/MemoryBuffer.h>
#include <boost/outcome.hpp>

namespace outcome = BOOST_OUTCOME_V2_NAMESPACE;

BOOST_OUTCOME_V2_NAMESPACE_BEGIN
// 泛化处理所有llvm::ErrorOr<T>类型
template<class T>
inline bool try_operation_has_value(const llvm::ErrorOr<T>& v)
{
  return static_cast<bool>(v);
}

template<class T>
inline auto try_operation_return_as(const llvm::ErrorOr<T>& v)
{
  // 仅在try_operation_has_value返回false时被调用,直接返回错误
  return outcome::failure(v.getError());
}

template<class T>
inline auto try_operation_extract_value(const llvm::ErrorOr<T>& v)
{
  // 返回ErrorOr内部的有效值,保持原类型(比如std::unique_ptr<T>)
  return *v;
}
BOOST_OUTCOME_V2_NAMESPACE_END

int test_stdin()
{
  BOOST_OUTCOME_TRY(const auto& ibuff, llvm::MemoryBuffer::getSTDIN());
  // 这里可以正常使用ibuff,类型为const std::unique_ptr<llvm::MemoryBuffer>&
  return 0;
}

关键修正点说明

  • 函数名修正:将try_return_as改为try_operation_return_as,匹配Boost Outcome的宏扩展要求。
  • 错误访问修正:用v.getError()替代v->getError(),确保失败时安全获取错误对象。
  • 模板泛化:将模板参数改为llvm::ErrorOr<T>,支持所有ErrorOr包装的类型,包括std::unique_ptr<T>、基础类型等,提升复用性。
  • 返回值完整性:try_operation_return_as仅在失败分支被调用,直接返回failure对象,避免无返回值的语法错误;try_operation_extract_value直接返回*v,保留原对象的类型和所有权语义。

内容的提问来源于stack exchange,提问作者Sean Champ

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 13:52:34