2015-05-29 18 views
11

mi piacerebbe fare qualcosa di simile (all'interno di una classe):array statico delle funzioni lambda (C++)

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

Dove MyStruct è definito come:

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

Ho anche provato:

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

per la definizione di fn, ma senza fortuna.

L'errore che ottengo per il primo caso è "errore: l'inizializzatore del campo non è costante" che non ottengo realmente. Se provo con std::function peggiora, dal momento che dice: "non può essere inizializzato da un'espressione non costante quando viene dichiarato".

Perché la funzione lambda non è costante? Mi sto perdendo qualcosa?

+1

Sostituire 'constexpr' con' const'. – Nawaz

+4

le espressioni lambda al momento potrebbero non verificarsi all'interno di espressioni costanti, ma tale restrizione potrebbe essere rimossa alla fine: https://isocpp.org/files/papers/N4487.pdf – dyp

risposta

9

Quando si costruisce constexpr oggetto, tutto si passa in esso deve essere un nucleo espressione costante, [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).

e, da [expr.const] lambda non sono costanti espressioni :

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

Tuttavia, che si applica solo ai constexpr e non const, così si potrebbe semplicemente fare questo, invece:

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

Nota: il tuo lambda non ha bisogno di catturare nulla, quindi dovresti solo la lista di cattura vuota [].


Come dyp punti fuori, c'è una proposta per cambiare questo: N4487

0

L'acquisizione di lambda non può decadere in funzione del puntatore.

e l'operatore per restituire il puntatore di funzione da una lambda (non acquisibile) non è constexpr.

Problemi correlati