Этот код генерирует SIGSEGV во время выполнения при компиляции с GCC (4.7.2-5ubuntu), но не Clang (Apple LLVM 4.2)
#include <functional>
#include <iostream>
using FuncType = std::function<int(int)>;
int func(FuncType f, int i) {
return f(i)+1;
}
struct Alpha {
FuncType f, g;
Alpha(FuncType f) : f(f) {
g = [&](int i) -> int {
return func(f, i);
};
}
int go(int i) {
return g(i);
}
};
struct Beta {
int k = 0;
Beta newBeta(int nk) {
Beta beta = *this;
beta.k = nk;
return beta;
}
};
struct Gamma {
Beta beta;
void go(int j) {
auto f = [&](int i) -> int {
int n = beta.newBeta(i).k+j;
return n*n;
};
Alpha alpha(f);
std::cout << alpha.go(beta.k) << std::endl;
}
};
int main(int argc, char *argv[]) {
Gamma gamma;
gamma.go(7);
return 0;
}
Отладка, сбой происходит, когда лямбда f
называется в func
, beta
сообщает как недопустимый объект, хотя он должен быть действительным при вызове лямбды.
Похоже, что это результат эта ошибка, но эта ошибка, как сообщается, была исправлена в 4.7.2.
Редактировать: Initialized Beta::k
для наглядности не влияет баг.
Одна проблема здесь:
Alpha(FuncType f) : f(f) {
g = [&](int i) -> int {
return func(f, i);
};
}
твоя лямбда обязательна f
(аргумент для конструктора и так локально для конструктора) по ссылке, поэтому после завершения конструктора эта ссылка будет зависать. Когда вы позже позвоните g
, вы получите неопределенное поведение, так как оно относится к этой висячей ссылке.
Изменить [&]
в [=]
привязать по значению, и все должно быть в порядке.
Других решений пока нет …