Ответ 1
Чтобы передать аргументы цели, вам необходимо предоставить эти аргументы в выражении привязки или оставить их несвязанными, добавив заполнители в выражение привязки, а затем вы должны вызвать функцию с аргументами, которые будут заменены заполнителями.
Вы можете вызвать bar1
без заполнителей, потому что он не принимает никаких аргументов, поэтому вам не нужно ничего передавать. Аргументы, которые вы передаете в f1
, просто игнорируются, потому что нет несвязанных аргументов, т.е. Нет заполнителей, которые нуждаются в замене.
Другие функции требуют аргументов, поэтому вы должны либо связывать аргументы с "временем связывания", например.
auto f2a = std::bind(&Foo::bar2, &foo, 1);
f2a();
или оставить аргументы несвязанными и предоставить их при вызове вызываемого объекта:
auto f2b = std::bind(&Foo::bar2, &foo, std::placeholders::_1);
f2b(1);
Обратите внимание, что GCC 5 теперь имеет статические утверждения, чтобы поймать такую ошибку. Если арность целевой функции может быть определена, и выражение привязки не имеет ни связанного аргумента, ни заполнителя для каждого параметра целевой функции, тогда он говорит:
/usr/local/gcc-head/include/С++/5.0.0/functional: 1426: 7: ошибка: статическое утверждение не выполнено: неправильное количество аргументов для указателя на элемент
То, что вы написали, эквивалентно этому, используя lambdas вместо bind
:
Foo foo;
auto f1 = [&foo](...) { return foo.bar1(); };
auto f2 = [&foo](...) { return foo.bar2(); };
auto f3 = [&foo](...) { return foo.bar3(); };
auto f4 = [&foo](...) { return foo.bar4(); };
f1(1, 2, 3, 4); // success
f2(1, 2, 3); // error
f3(1, 2); // error
f4(1); // error
то есть. вы определяете функторы, которые будут принимать любые аргументы, но игнорировать их, а затем вызывать функции-члены Foo
, но не обязательно с правильными аргументами.