Почему я не могу использовать boost :: function в блоке Objective-C ++? - PullRequest
3 голосов
/ 26 марта 2011

Следующий код генерирует исключение

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 ]

1 голос
/ 06 апреля 2011

Похоже, что если я изменю объявление с помощью __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", я не уверен, что будет.

0 голосов
/ 09 апреля 2011

Пример в вашем ответе

const boost::function<void()> f = boost::bind(&foo);
const boost::function<void()> g(f);
g();

работает, потому что вы вызываете operator() в той же области, в которой был создан его вызываемый объект.f() будет работать и за пределами области видимости блока, а вызов foo() будет работать внутри области видимости блока, потому что это классическая функция и не считается "модифицированной" при вызове.Ссылочный вызов конструктора const copy выполняется при передаче объекта из области видимости в область блока.Казалось бы, что бы ни существовало различие в конструкторе const copy, не может скопировать часть объекта, чтобы заблокировать область видимости.

...