templates - 模板表达式的默认参数

标签 templates nim-lang default-arguments

如果我想制作一个可以接受2个无类型参数的模板,并通过do表示法传递它们,当我省略第二个do时> 我希望有一种方法以参数默认值的形式指定后备。像这样:

template tpl(x: bool, body: untyped, bodyFinally: untyped): void =
  if x: body
  else: bodyFinally

#call site:
var r: int
tpl(true) do:
  r = 2
do:
  raise newException(Exception, "")

这可行,但是:

template tpl(x: bool, body: untyped, bodyFinally: untyped = discard): void =
  # same rest

Error: expression expected, but found 'keyword discard'

不接受默认值,而且消息很奇怪,discard 是一个表达式,不是吗。

尝试解决方法:

template tpl(x: bool, body: untyped, bodyFinally: untyped = proc()): void =
  # same rest

然后我们得到:

Error: expression 'proc ()' is of type 'type proc (){.closure.}' and has to be discarded

我已经准备好接受这一点,尽管我发现这个discard要求毫无用处,而且对语言来说很麻烦,因为它迫使我们在像这里这样的通用代码中进行不舒服的体操。

让我们再次编辑:

template tpl(x: bool, body: untyped, bodyFinally: untyped = proc()): void =
  if x: body
  else: discard bodyFinally

现在的结果是:

Error: internal error: expr(nkProcTy); unknown node kind

最佳答案

确实没有办法将代码块描述为默认参数值。有两种可能的解决方法:

1) 您可以通过重载来模拟默认值:

template tpl(x: bool, body: untyped, bodyFinally: untyped) =
  if x: body
  else: bodyFinally

template tpl(x: bool, body: untyped): void =
  tpl(x) do:
    body
  do:
    discard

第二个重载的另一个较短版本是这样的:

template tpl(x: bool, body: untyped): void =
  tpl(x, body, (discard))

2) 您可以使用可在模板内检测到的默认值,例如 nil:

import macros

template tpl(x: bool, body: untyped, bodyFinally: untyped = nil) =
  if x:
    body
  else:
    when astToStr(bodyFinally) == "nil":
      discard
    else:
      bodyFinally

请注意,我必须使用 astToStr,因为当用户提供 a 时,无法将 bodyFinallynil 进行比较非默认值。

关于templates - 模板表达式的默认参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49613003/

相关文章:

python - 如何处理 argparse 中缺少的参数?

C++ 模板运算符重载 std::enable_if

c++ - 有没有办法改变概念内复合需求返回的类型?

enums - Nim : standard way to convert integer/string to enum

linux - 我如何检查文件是否是 nim 中的可执行文件?

javascript - 在带有 Emscripten 的 Nim 中使用字符串会导致 JavaScript 错误

c++ - 指定默认参数 C++

c++ - 错误 : "incomplete type is not allowed" while porting project

c++ - 表达式模板的模板化返回类型特化

c++ - 是否可以使用成员函数调用作为默认参数?