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

时间:2012-12-29 21:10:50

标签: c++ c++11 lambda constexpr

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

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);
}

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

3 个答案:

答案 0 :(得分:10)

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

  

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

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

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

答案 1 :(得分:7)

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

  

某些上下文需要满足额外条件的表达式   本条款详述的要求;其他情况有   不同的语义取决于表达是否令人满意   这些要求。满足这些要求的表达是   称为常量表达式。 [注意:常量表达式可以是   在翻译期间进行评估.-结束语]

接着说:

  

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

其下的哪个列表:

  

- lambda表达式(5.1.2);

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

答案 2 :(得分:5)

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

  

错误:调用非constexpr函数'addition()::
  &LT;拉姆达(INT,INT)GT; ::
   operator int(*)(int,int)()const '

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