2015-05-29 68 views
11

我想這樣做(一類中)靜態數組:lambda函數(C++)

static constexpr MyStruct ops[6] = { 
    {'+', [&] (double a, double b) { return a+b; } }, 
    {'-', [&] (double a, double b) { return a-b; } }, 
    ... 
}; 

MyStruct定義爲:

typedef double (*binOp)(double, double); 
struct MyStruct { 
    char c; 
    binOp fn; 
}; 

我也嘗試:

std::function <double(double,double)> fn; 

定義fn,但沒有運氣。

我得到的第一個案例的錯誤是「錯誤:字段初始值設定項不是常量」我真的不明白。如果我嘗試使用std::function,它會變得更糟,因爲它說:「聲明時不能用非常量表達式初始化」。

爲什麼lambda函數不是常量?我錯過了什麼嗎?

+1

替換'和'const' constexpr'。 – Nawaz

+4

lambda表達式當前可能不會出現在常量表達式中,但是最終可能會刪除該限制:https://isocpp.org/files/papers/N4487.pdf – dyp

回答

9

當構造constexpr對象,就通入它的一切必須是一個核心常量表達式,[decl.constexpr]/9:

A constexpr specifier used in an object declaration declares the object as const . Such an object shall have literal type and shall be initialized. If it is initialized by a constructor call, that call shall be a constant expression (5.19).

和,從[expr.const] lambda表達式不是恆定表達式:

A conditional-expressione is a core constant expression unless the evaluation of e, following the rules of the abstract machine (1.9), would evaluate one of the following expressions:

  • [...]
  • a lambda-expression (5.1.2);
  • [...]

然而,這僅適用於constexpr,而不是const,所以你可以簡單地這樣做,而不是:

static const MyStruct ops[6] = { 
    {'+', [] (double a, double b) { return a+b; } }, 
    {'-', [] (double a, double b) { return a-b; } }, 
}; 

注意:你的lambdas不需要捕獲任何東西,所以你應該只是空的捕獲列表[]


作爲dyp指出的,就是要改變這樣的建議:N4487

0

捕獲lambda不能衰減到函數指針。

和運算符從(非捕獲)lambda返回函數指針不是constexpr