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

mil*_*bug 20 c++ lambda constexpr c++11

我发现这段代码不起作用:

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);
}
Run Code Online (Sandbox Code Playgroud)

它给了我错误

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'
Run Code Online (Sandbox Code Playgroud)

这是为什么?我不是在这里打电话.

直接进场工作:

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);
}
Run Code Online (Sandbox Code Playgroud)

我正在使用MinGW和g ++版本4.7.2.

And*_*owl 10

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

从7.1.5开始:"constexpr函数的定义应满足以下约束条件:

  • 它不应是虚拟的(10.3);
  • 其返回类型应为字面类型 ;
  • 每个参数类型都应是文字类型;
  • 它的函数体应为= delete,= default 或仅包含的复合语句
    • 空语句,
    • static_assert申述
    • typedef声明和不定义类或枚举的别名声明,
    • 使用申述,
    • using指令,
    • 而且只有一个退货声明 ;"

我不认为这里有任何错误,尤其是在前面的答案中提到的与lambdas无关:变量根本不能在constexpr函数内声明.


Rap*_*ptz 7

根据N3376标准第5.19节[expr.const]的工作草案:

某些上下文要求表达式满足本子条款中详述的其他要求; 其他语境具有不同的语义,取决于表达式是否满足这些要求.满足这些要求的表达式称为常量表达式.[注意:在翻译期间可以评估常量表达式.-结束注释]

它继续说:

条件表达式是核心常量表达式,除非它涉及以下之一作为潜在评估的子表达式(3.2),但是未评估的逻辑AND(5.14),逻辑OR(5.15)和条件(5.16)操作的子表达式不考虑[注意:重载运算符调用函数.-结束注释]:

下面列出了哪些列表:

- lambda表达式(5.1.2);

因此,虽然我不知道足够的标准,但我相信这表明constexpr内部不应该有lambda表达式.


ric*_*ici 6

gcc给出的错误消息是准确无误的:

error:调用非constexpr函数'addition()::
             <lambda(int,int)> ::
             operator int(*)(int,int)()const '

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