Почему я не могу использовать boost::function в блоке Objective-C++?
Следующий код выдает исключение
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::bad_function_call> >'
what(): call to empty boost::function
на линии f()
(при выполнении блока):
void foo(); // assume this is defined somewhere
boost::function<void()> f = boost::bind(&foo);
^(void) {
f();
}();
Однако, согласно документации на блоки,
В общем, вы можете использовать объекты C++ внутри блока. Внутри функции-члена ссылки на переменные-члены и функции через неявно импортируются этот указатель и, следовательно, выглядят изменяемыми. При копировании блока применяются два соображения:
Если у вас есть класс хранения __block для того, что было бы объектом C++ на основе стека, то используется обычный конструктор копирования.
Если вы используете какой-либо другой объект на основе стека C++ изнутри блока, он должен иметь конструктор const copy. Затем объект C++ копируется с использованием этого конструктора.
Кажется, это правда, как обычно; если я заменю f
выше с экземпляром простого класса с operator()()
приведенный выше код работает как ожидалось.
Почему не версия с boost::function
Работа?
2 ответа
Похоже, что если я изменю объявление с __block
работает правильно:
__block boost::function<void()> f = boost::bind(&foo);
Я до сих пор не уверен, почему это так - как упоминает @Richard в комментарии выше, это должно быть связано с "конструктором копирования const", а не с "обычным конструктором копирования". Я не знаю, как проверить эту разницу, хотя; Следующее работает отлично:
const boost::function<void()> f = boost::bind(&foo);
const boost::function<void()> g(f);
g();
и если это не вызывает "конструктор const copy", я не уверен, что будет.
Пример в вашем ответе,
const boost::function<void()> f = boost::bind(&foo);
const boost::function<void()> g(f);
g();
работает потому что ты звонишь operator()
в том же объеме, в котором был создан его вызываемый. f()
будет работать за пределами области видимости блока, и вызов foo()
будет работать внутри области видимости блока, потому что это классическая функция, которая не считается "модифицированной" при вызове. Указанный вызов конструктора const copy выполняется при передаче объекта из области видимости в область блока. Казалось бы, что бы ни существовало различие в конструкторе копирования const, ему не удается скопировать часть объекта в область видимости.