2015-05-29 14 views
11

Tôi muốn làm điều gì đó như thế này (bên trong một lớp):mảng tĩnh của các hàm lambda (C++)

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

đâu MyStruct được định nghĩa là:

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

Tôi cũng đã cố gắng:

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

để định nghĩa fn, nhưng không may mắn.

Lỗi tôi nhận được cho trường hợp đầu tiên là "lỗi: trình khởi tạo trường không cố định" mà tôi không thực sự nhận được. Nếu tôi thử với std::function nó trở nên tồi tệ hơn, vì nó nói: "không thể được khởi tạo bởi một biểu thức không liên tục khi được khai báo".

Tại sao hàm lambda không liên tục? Tui bỏ lỡ điều gì vậy?

+1

Thay thế 'constexpr' với 'const'. – Nawaz

+4

biểu thức lambda hiện tại có thể không xảy ra bên trong biểu thức không đổi, nhưng hạn chế đó có thể bị xóa cuối cùng: https://isocpp.org/files/papers/N4487.pdf – dyp

Trả lời

9

Khi bạn xây dựng constexpr đối tượng, tất cả mọi thứ bạn vượt qua thành nó cần phải được một biểu thức hằng lõi, [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).

và, từ [expr.const] lambdas không liên tục biểu :

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);
  • [...]

Tuy nhiên, đó chỉ áp dụng cho constexpr và không const, vì vậy bạn chỉ có thể làm điều đó thay vì:

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

Lưu ý: lambda của bạn không cần chụp bất kỳ thứ gì, vì vậy bạn chỉ nên lấy danh sách chụp trống [].


Như dyp điểm ra, có một đề nghị để thay đổi điều này: N4487

0

chụp lambda không thể phân rã thành con trỏ chức năng.

và toán tử trả về con trỏ hàm từ lambda (không bắt) không phải là constexpr.