2012-10-17 10 views
13

Przypisuję do std::function<double()> wyrażenie lambda. Ten fragment działaOperator potrójny nie działa z funkcjami lambda.

if(fn_type==exponential) 
    k.*variable = [=,&k](){ return initial*exp(-k.kstep*par); }; 
else 
    k.*variable = [=,&k](){ return initial*pow(k.kstep, par); }; 

natomiast jeśli chcę użyć operatora trójskładnikowych

k.*variable = (fn_type==exponential ? [=,&k](){ return initial*exp(-k.kstep*par); } : [=,&k](){ return initial*pow(k.kstep, par); }); 

pojawia się następujący błąd:

error: no match for ternary ‘operator?:’ in <awfully long template error, because this whole thing is in a class defined in a function...> 

Czy jest to błąd gcc (używam 4.7 .2)? W przeciwnym razie, dlaczego istnieje taki limit w standardzie?

Odpowiedz

18

Drugi i trzeci operand operatora warunkowego musi być tego samego typu lub musi istnieć jakiś wspólny typ, do którego mogą być konwertowane zarówno kompilator, jak i program. Istnieje tylko garstka konwersji, które rozważy kompilator.

Twoje dwa wyrażenia lambda mają różne typy, a nie ma wspólnego typu, do którego mogą być zarówno Budynek (konwersji do typów zdefiniowanych przez użytkownika, jak std::function<double()>, nie można uznać, ponieważ istnieje potencjalnie nieskończonej liczby poprawnych typów docelowych).

można bezpośrednio przekształcić każdy z argumentów do std::function<double()>:

k.*variable = fn_type==exponential 
    ? std::function<double()>([=,&k](){ return initial*exp(-k.kstep*par); }) 
    : std::function<double()>([=,&k](){ return initial*pow(k.kstep, par); }); 

Ale tak naprawdę, to odkurzacz z if/else.

+2

+1 za odpowiedź, kolejne +1 za "jest czystsze dzięki temu/else". –

Powiązane problemy