如何在cpp中编写这个可以从函数返回的宏

Posted

技术标签:

【中文标题】如何在cpp中编写这个可以从函数返回的宏【英文标题】:How to write this macro in cpp that can return from the function 【发布时间】:2021-06-13 03:36:37 【问题描述】:

我正在使用 cpp 变体来指示我的程序中的错误,例如,我有一个这样的函数:

std::variant<Result, Error> do_foo();

std::variant<string, Error> do_bar() 
  auto v = do_foo();
  if (std::holds_alternative<Error>(v)) 
    return std::get<Error>(v);
  
  auto r = std::get<Result>(v);
  // do some more stuff with r
  return some_str;

但我最终检查了很多次错误并且很乏味,所以我想写一个宏,我们称之为保释,以缩短它。所以 do_bar 可能看起来像这样:

std::variant<string, Error> do_bar() 
  Result r = bail(do_foo()); // it should return if do_foo() returns an error
  // do some more stuff with r
  return some_str;

虽然不确定如何编写该宏,但这里有一些不起作用的尝试:

#define bail(v)  auto _v = v; \
  if (_v.index() == 1) return std::get<1>(_v); \
  std::get<0>(_v); 

但是,那个块并没有给我任何价值。请注意,我试图避免异常。任何帮助表示赞赏!

【问题讨论】:

你想避免什么异常?因为这就是异常的用途。 宏错误。使用 lambda。 @Casey lambda 不允许我返回外部函数。我很想知道那是不是真的。 @SamVarshavchik 异常非常丑陋。很多人在 C++ 中避免异常,例如,谷歌在他们的代码库中很大程度上禁止了异常。 GCC 有 statement expressions 作为扩展,但它不是可移植的。 【参考方案1】:

在可移植 C++ 中无法实现您想要的。如果你使用 gcc 或 clang,你可以使用statement exprs。我真的建议您不要这样做,但这里是您提出的问题的答案:

// Non-portable--you probably shouldn't do this
#define bail(v) (            \
    auto _v = v;              \
    if (_v.index() == 1)      \
      return std::get<1>(_v); \
    std::get<0>(_v);          \
  )

【讨论】:

以上是关于如何在cpp中编写这个可以从函数返回的宏的主要内容,如果未能解决你的问题,请参考以下文章

在命名空间中,如何定义从内部类返回对象的函数?

是否可以编写一个在函数范围内使用时会报错的宏?

如何从函数返回数据类型 int** 并存储它?

如何在 .h 和 .cpp 中为类中的私有 char 数组编写 get 函数?

如何在生锈的宏文档中添加示例?

如何编组从 C 头文件中的宏定义的结构?