1. Действительно ли x(123)
называет operator()
функтора, который сгенерировал std::function
, который, в свою очередь, вызывает operator()
функтора, который сгенерировал std::bind
, который, наконец, называет func
? Это оптимизируется во что-то оптимальное, как вызов func(123)
?
Если у вас включена оптимизация, «материал» встраивается, и вы можете рассчитывать на то, что это будет оптимальным, как вызов func(123)
.
2. Где живет функтор, который генерирует std::bind
? В каком объеме? И как это называется std::bind
? (Может ли быть столкновения имен)
Precising: bind
генерирует «», мимолетное реализации определенного, связать выражение, то есть, присваиваемые function<>
. Функция - это просто шаблон класса (спасибо, Люк Т.). И он живет в стандартной библиотеке. Однако выражения привязки определяются реализацией.
В стандартной библиотеке имеются признаки (std::is_bind_expression<>
), позволяющие определять такие выражения MPL. Одной из решающих особенностей выражений связывания над std :: function является то, что они (я бы назвал) отложенными вызываемыми объектами (т. Е. Что они сохраняют полную семантику сайта вызова, включая возможность выбора перегрузок на фактическом сайте приложения). std::function<>
, с другой стороны, фиксирует один прототип и внутренне сохраняет callable object по типу стирания (думаю variant
или any
).
3. Может ли lambdas заменить все виды использования std :: bind?
4. Является ли std :: bind оптимальным, если вместо него использовать лямбда?
AFAICT lambdas должен скомпилироваться примерно так же, как выражения привязки. Одна вещь, которую я думаю лямбды не может сделать что связываемые выражения может является nested bind expressions
Редактировать Хотя конкретные идиома вложенных выражений связывания не replicatable с использованием лямбды, лямбды, конечно, в состоянии выразить (почти) то же самое гораздо более естественно:
bind(f, bind(g, _1))(x);
// vs.
[](int x) { f(g(x)); };
5. Что случилось с синтаксисом аргумента шаблона std::function
? Как это анализируется и как я могу использовать синтаксис аргумента шаблона в другом месте?
Это просто функция подписи (тип функции), передается в качестве параметра шаблона.
Вы также можете использовать его как тип параметра функции, который деградирует указателю функции (аналогично тому, как параметры по умолчанию массива ухудшаются до указателей, спасибо Дэвиду!). На практике, большинство в любом месте, до тех пор, пока вы не имеете потребность в имени переменная/тип:
void receiveFunction(void(int, double)); // spunky 'function<>'-style syntax
void sample(int, double) { }
int main()
{
receiveFunction(sample);
}
void receiveFunction(void (*f)(int, double)) // boring 'old' style syntax
// void (f)(int, double) // ... also ok
{
// ..
}
Для 2. вас может заинтересовать http://www.artima.com/cppsource/type_erasure.html – Flexo
Один вопрос за один раз, пожалуйста. Каждый вопрос о СО является вопросом. –
Это скорее набор вопросов, чем конкретный вопрос, и они варьируются от синтаксиса (для аргумента функции <> ') до поведения (где результат live live? Может заменить лямбда?) Производительность (будет он оптимизирован?) –