#c #std-function #stdbind
#c #std-функция #stdbind
Вопрос:
Я пытаюсь понять, как работают std::bind и std::функция. Я не могу получить следующий код для компиляции:
#include <iostream>
#include <string>
#include <functional>
void function(int a, float b, std::string const amp;s)
{
std::cout << "printing function" << std::endl;
std::cout << a << std::endl;
std::cout << b << std::endl;
std::cout << s << std::endl;
}
int main(int argc, char *argv[])
{
std::bind(amp;function, 10, 11.1, "hello")();
std::function<void(int, float, std::string constamp;)> fun = std::bind(amp;function, 10, std::placeholders::_1, std::placeholders::_2);
fun(0.2, "world");
return 0;
}
компилятор жалуется, что:
main.cpp: In function 'int main(int, char**)':
main.cpp:16:69: error: conversion from 'std::_Bind_helper<false, void (*)(int, float, const std::__cxx11::basic_string<char>amp;), int, const std::_Placeholder<1>amp;, const std::_Placeholder<2>amp;>::type {aka std::_Bind<void (*(int, std::_Placeholder<1>, std::_Placeholder<2>))(int, float, const std::__cxx11::basic_string<char>amp;)>}' to non-scalar type 'std::function<void(int, float, const std::__cxx11::basic_string<char>amp;)>' requested
std::function<void(int, float, std::string constamp;)> fun = std::bind(amp;function, 10, std::placeholders::_1, std::placeholders::_2);
~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
пожалуйста, кто-нибудь может объяснить? и как мне исправить эту ошибку?
Комментарии:
1. После того, как вы привязали
a
к10
, остается толькоvoid(float, std::string constamp;)
.2. Также обратите внимание, что
std::bind
это не рекомендуется в C 17, и что использование lambda является более предпочтительным.auto fun = [](float a, std::string constamp; b) { function(10, a, b); };
3. Возможно, стоит отметить, что в современном коде лямбды всегда предпочтительнее, чем std::bind now.
4. @Zereges
std::bind
никоим образом не является устаревшим.std::bind1st
и т.д. Устарели, ноstd::bind
все еще имеют некоторые применения: sdowney.org/2017/06/why-stdbind-cant-be-formally-deprecated5. @AlanBirtles Вы правы, я понятия не имею, почему я думал, что это устарело
Ответ №1:
Вы почти у цели, просто измените тип fun
на
std::function<void(float, std::string constamp;)> fun = std::bind(...);
// ^^ no more int here
fun(0.2, "world");
// ^^^^^^^^^^^^ those types must match the above signature
Обратите внимание, что вы меняете сигнатуру функции при исправлении первого аргумента функции типа int
на значение 10
. Следовательно, это не может быть типом std::function
экземпляра.
Далее обратите внимание, что Скотт Мейерс предлагает в пункте 34 «Эффективный современный C » заменить std::bind
использование лямбдой, например
auto fun = [](float b, std::string constamp; s){ function(10, b, s); };
// Identical invocation:
fun(0.2, "world");
Комментарии:
1. Я бы предложил использовать
auto
там.2. @Zereges Это тоже устраняет проблему, но в первую очередь скрывает причину сбоя.
3. Я бы оставил объяснение как есть, но также предложил использовать
auto
вместо сложного возвращаемого типа.4. Черт возьми, я опаздываю на 5 минут.