Re: bind и ошибки компиляции
От: Кодт Россия  
Дата: 25.09.13 19:24
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Объясните, пожалуйста, почему следующий код не компилируется?

Потому что конструкция из вложенных биндов — это не замыкание с замыканием, а одно большое замыкание.
(Потому что std::bind — не просто функция высшего порядка, но ещё и конструктор Expression Template).

Если внутрений бинд отдельно скопировать в function, то он будет изолирован от внешнего.
Чтобы изолировать по месту, достаточно написать boost::protect
std::thread th(std::bind(foo, std::bind(callback_function, 0, 1.0)));
// эквивалентно
std::thread th(
  []()
  {
    foo(callback_function(0, 1.0));
  }
);

std::thread th(std::bind(foo, boost::protect(std::bind(callback_function, 0, 1.0))));
// эквивалентно
std::thread th(
  []()
  {
    foo(
      []() { callback_function(0, 1.0); }
    );
  }
);

Почему-то в 11 стандарт boost::protect не попал, поэтому нужно или подключить буст, или написать вручную
template<class T>
struct protector
{
    T t;

    protector(T const& t) : t(t) {}
    protector(T&& t) : t(t) {}

    template<class... A>
    auto operator()(A... a) -> decltype(t(a...)) const { return t(a...); }
};
template<class T> protector<T> protect(T&& t) { return protector<T>(t); }


Но, поскольку foo всё равно принимает std::function, то можно вместо protect прямо написать
std::thread th(std::bind(foo, std::function<void()>(std::bind(callback_function, 0, 1.0))));

Или, раз мы всё равно в 11 стандарте, написать лямбдами. С ними, как мне кажется, это и нагляднее будет.
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.