Привязка функций-членов

#c #boost #function-pointers

#c #повышение #указатели на функции

Вопрос:

В примере из раздела функции-члены: Функции-члены Мы получили структуру X:

 struct X {
  int foo(int);
};
  

Предпочитаемый синтаксис

 boost::function<int (X*, int)> f;

f = amp;X::foo;

X x;
f(amp;x, 5);
  

Переносимый синтаксис

 boost::function2<int, X*, int> f;

f = amp;X::foo;

X x;
f(amp;x, 5);
  

Мои вопросы:

  • Почему я должен вводить дополнительный аргумент X *, когда мой int foo (int) принимает только один аргумент? Кроме того, это то же самое, что использовать boost::bind, например:

Person *person = новый Person(«Tu», 23);

boost::функция newFunc2 = boost::bind(amp;Person::printInfo,person);

  • В чем разница между синтаксисом prefer и переносимым синтаксисом и когда использовать один вместо другого?
  • Что такое объект функции? Это указатель на функцию?

Ответ №1:

  1. Любая функция-член имеет указатель на объект, с которым нужно работать, неявно установленный в качестве ее первого параметра. Когда у вас есть код, подобный этому: X x; x.foo(10); компилятор действительно может вызывать foo(amp;x, 10) для вас (смотрите здесь два способа, которыми это может быть обработано) — очевидно, что имя foo было бы каким-то образом искажено.

  2. Смотрите документацию по Boost для описания синтаксиса. Ниже приведен наиболее релевантный отрывок со страницы. В принципе, вам следует использовать предпочтительную версию, если ваш компилятор поддерживает ее, поскольку она наиболее близка к обычному определению указателя на функцию (удобочитаемость) и использует меньше аргументов шаблона (более быстрое время компиляции).

    Повышение.Функция имеет две синтаксические формы: предпочтительную форму и переносимую форму. Предпочтительная форма более точно соответствует языку C и уменьшает количество отдельных параметров шаблона, которые необходимо учитывать, часто улучшая читаемость; однако предпочтительная форма поддерживается не на всех платформах из-за ошибок компилятора. Совместимая форма будет работать на всех компиляторах, поддерживаемых Boost.Функция. Обратитесь к таблице ниже, чтобы определить, какую синтаксическую форму использовать для вашего компилятора.

  3. Указатель на функцию — это обычный старый указатель, который случайно принимает функции с определенным типом возвращаемого значения и списком аргументов. Функциональный объект — это любой тип, который имеет operator() определенный, позволяющий вызывать его как функцию.

Комментарии:

1. 1. в зависимости от компилятора Visual C передает this в регистр ecx iirc.

2. @Xeo, хороший вызов, я этого не знал — я обновил ответ и ссылался на упоминание об этом в Википедии.

Ответ №2:

  1. Вам нужно передать объект типа X, потому что это указатель на функцию-член. Вам нужен объект, для которого вы вызываете эту функцию-член.

  2. переносимый синтаксис предназначен для старых и более новых компиляторов, а предпочитаемый синтаксис не может компилироваться на старых компиляторах. Подробное различие объясняется на странице руководства по функторам

  3. функциональный объект — это такой объект, который вы можете вызывать как функцию. Это может быть указатель на функцию или указатель на функцию-член

Комментарии:

1. @Xeo Я не уверен, что ты имеешь в виду. Эта ссылка : boost.org/doc/libs/1_41_0/doc/html/function/tutorial.html объясняет разницу, и вот как я понял

2. Предпочтительный синтаксис предназначен для тех компиляторов, которые его поддерживают, portable — это, ну, в общем, переносимый и поддерживаемый на большем количестве компиляторов (почти на всех). Сами значения этих слов должны это объяснить. Preferred назван так потому, что мы хотели бы использовать его везде, но не можем, а portable доступен в большом количестве компиляторов. Ваша ссылка даже показывает это в таблице!