2012-10-17 19 views
13

Tôi đang gán cho một biểu thức lambda std::function<double()>. đoạn này hoạt độngtoán tử ternary không hoạt động với các hàm lambda

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

trong khi nếu tôi muốn sử dụng các nhà điều hành ternary

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

tôi nhận được lỗi sau:

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

này một lỗi gcc Is (Tôi đang sử dụng 4,7 .2)? Nếu không thì tại sao có giới hạn này trong tiêu chuẩn?

Trả lời

18

Toán hạng thứ hai và thứ ba của toán tử có điều kiện phải có cùng loại hoặc phải có một số loại phổ biến mà cả hai có thể được chuyển đổi mà trình biên dịch có thể tìm ra. Chỉ có một số ít các chuyển đổi mà trình biên dịch sẽ xem xét.

Hai biểu thức lambda của bạn có các loại khác nhau và không có loại nào được chuyển đổi (chuyển đổi thành loại do người dùng xác định, như std::function<double()>, không thể xem xét vì có thể có vô số loại mục tiêu hợp lệ).

Bạn có thể trực tiếp chuyển đổi mỗi toán hạng để 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); }); 

Nhưng thực sự, nó sạch hơn với if/else.

+2

+1 cho câu trả lời, +1 khác cho "nó sạch hơn với if/else". –