【问题标题】:Why is a constexpr local variable not allowed as a default function parameter?为什么不允许将 constexpr 局部变量作为默认函数参数?
【发布时间】:2021-02-23 00:01:14
【问题描述】:

我想我明白为什么 C++ 不允许 local 变量作为默认函数参数:

int main () {
   auto local{1024};
   auto lambda = [](auto arg1 = local){};    // "illegal use of local variable as default parameter"
}

但即使该变量是 constexpr local 也是不允许的:

int main () {
   constexpr auto local{1024};
   auto lambda = [](auto arg1 = local){};    // "illegal use of local variable as default parameter"
}

但是,全局变量(即使是非constexpr)是允许的:

int global;
int main () {
   auto lambda = [](int arg1 = global){};    // OK
}

有人可以解释在这种情况下不允许 constexpr 局部变量的理由吗?当默认值是固定的并且在编译时已知时,编译器似乎应该能够为函数构造适当的“默认参数”重载。

【问题讨论】:

  • 你可以制作本地的static,除了一些奇怪的递归情况外,这通常是个好主意。

标签: c++ constexpr default-arguments


【解决方案1】:

这是一个关于生命周期的问题。让我们将您的功能修改为

auto get_functor() {
   constexpr auto local{1024};
   return [](auto arg1 = local){};    // "illegal use of local variable as default parameter"
}

现在,在get_functor 的调用点,您会得到一个 lambda,其默认值是不再存在的对象的值。由于每次调用函数时都会计算默认参数,而相应参数没有参数,因此您需要初始化表达式在所有范围内都有效。

【讨论】:

  • 谢谢。我想我只是期望一个 constexpr 变量,其值在编译时已知,无论范围如何,都将是一个有效的默认参数,因为在运行时任何给定点使用的值永远不会有任何歧义。但我认为 constexpr 局部变量仍然在堆栈中进出,并且与封闭函数的临时内存空间相关,而不是被替换到编译代码中的东西(就像宏被替换到预编译代码中)。
  • @NKatUT 这很可能可以实现,编译器只是为我们合成了一个全局变量,这还没有完成。很可能有人需要编写提案以更改标准以允许本地编译时常量变量。
猜你喜欢
  • 2012-02-14
  • 2015-02-19
  • 1970-01-01
  • 2017-12-29
  • 2023-03-27
  • 2012-01-02
  • 2018-04-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多