为什么我的 constexpr 函数不能返回 lambda?

Why can't my constexpr function return a lambda?

本文关键字:返回 lambda 不能 函数 我的 constexpr 为什么      更新时间:2023-10-16

我发现这段代码不工作:

typedef int (*fp)(int a, int b);
constexpr fp addition()
{
    return [](int a, int b){ return a+b; };
}
#include <iostream>
int main()
{
    fp fun = addition();
    std::cout << fun(2,2);
}

显示错误

cexpr.cpp: In function 'constexpr int (* addition())(int, int)':
cexpr.cpp:5:43: error: call to non-constexpr function 'addition()::<lambda(int,
int)>::operator int (*)(int, int)() const'

为什么?我不在这里调用它

直接方法有效:

typedef int (*fp)(int a, int b);
#include <iostream>
int main()
{
    fp fun = [](int a, int b){ return a+b; };
    std::cout << fun(2,2);
}

我使用的是g++ 4.7.2版本的MinGW

您的函数fp()不返回文字类型,因此它不能是constexpr函数:

来自7.1.5:" constexpr函数的定义必须满足以下约束:

  • 它不应该是虚拟的(10.3);
  • 其返回类型应为文字类型;
  • 它的每一个参数类型必须是文字类型;
  • 的函数体应该是= delete、= default、或者只包含的复合语句。
    • 空语句,
    • static_assert-declarations
    • 类型定义声明和别名-不定义类或枚举的声明,
    • 通过声明,
    • using引用
    • 和一个返回语句;"

我不认为这里有任何错误,特别是在前面的回答中提到的与lambda无关:变量不能在constexpr函数中声明。

根据N3376工作草案标准第5.19节[expr]。常量:

某些上下文需要满足附加条件的表达式本款中详细说明的要求;其他情况有不同的语义取决于表达式是否满足这些要求。满足这些要求的表达式是叫做常量表达式。[注:常量表达式可以是。在翻译过程中评估。

它接着说:

条件表达式是核心常量表达式,除非它包含以下一个可能求值的子表达式(3.2),但逻辑与(5.14)、逻辑或(5.15)、不求值的条件(5.16)操作不求值注意:重载操作符调用函数。- - -结束注意:

下面的列表:

- lambda表达式(5.1.2);

所以,虽然我不知道足够的标准,我相信这是说constexpr不应该有一个lambda表达式在里面。

gcc给你的错误信息是精确和正确的:

错误:调用非constexpr函数'addition()::
,,,,,,,,,,,, & lt;λ(int, int)祝辞::
,,,,,,,,,,,, 操作符int (*) (int, int)()常量"

我重新格式化了一下,并增加了重点。通过将lambda强制转换为函数指针,您将隐式地调用自动创建的从lambda到pointer to function of type "auto (int, int)->int"的转换函数,这不是constexpr函数,因为自动创建的转换函数没有声明为constexpr(标准也不要求如此)。