Почему не видит функцию?
- Можете объяснить почему в методе run std::bind не видет void write(std::string && msg)?
- как можно изменить код (не меняя интерфейс класса), чтобы решить эту проблему?
- есть ли пример концепта для метода run? я имею ввиду концепт, который будет проверять что Func и переменное кол-во аргументов - исполняемый объект?
#include <iostream>
#include <functional>
struct Foo {
void add(std::string && msg) {
run(&Foo::write, this, std::move(msg));
}
template<class Func, class ...Args>
void run(Func && func, Args && ... args) {
auto task = std::bind(std::forward<Func>(func), std::forward<Args>(args)...);
task();
}
void write(std::string && msg) {
std::cout << "Foo::write " << msg << '\n';
}
};
int main()
{
Foo foo;
foo.add("hello!");
return 0;
}
upd сама ошибка
main.cpp:18:13: error: no match for call to ‘(const std::_Bind))(std::basic_string&&)>) ()’
task();
~~~~^~
In file included from main.cpp:10:0:
/usr/include/c++/7/functional:547:2: note: candidate: template _Result std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args&& ...) [with _Args = {_Args ...}; _Result = _Result; _Functor = void (Foo::*)(std::basic_string&&); _Bound_args = {Foo*, std::basic_string, std::allocator >}]
operator()(_Args&&... __args)
Ответы (1 шт):
Просто исправьте функцию write на такую
void write(const std::string& msg) {
std::cout << "Foo::write " << msg << '\n';
}
ну не знает bind о том, что нужно Ваш аргумент передавать таким способом. и не находит подходящей перегрузки
Можете объяснить почему в методе run std::bind не видет void write(std::string && msg)?
Потому что bind на самом деле создает функциональный объект (грубо говоря класс, где переданные параметры - переменные этого класса. А они по определению не будут rvalue).
как можно изменить код (не меняя интерфейс класса), чтобы решить эту проблему?
В вопросе немного не видно, где интерфейс класса, а где нет. Но если где то не работает bind, то нужно использовать лямбды. Маерс в своей книге утверждает, что есть только один случай, где bind ему кажется красивее.
В процессе экспериментов, родился вот такой франкинштейн (поэтому не ругайте:) ). Насколько он "не нарушает интерфейсов", я не знаю. Но он компилируется и работает.
#include <iostream>
#include <functional>
struct Foo {
void add(std::string && msg) {
run([&](std::string&&s) {this->write(std::move(s));}, std::move(msg));
}
template<class Func, class ...Args>
void run(Func func, Args && ... args) {
auto task = [&]() { func(std::forward<Args>(args)...); };
task();
}
void write(std::string&& msg) {
std::cout << "Foo::write " << msg << '\n';
}
};
int main()
{
Foo foo;
foo.add("hello!");
return 0;
}
есть ли пример концепта для метода run? я имею ввиду концепт, который будет проверять что Func и переменное кол-во аргументов - исполняемый объект?
я не думаю, что они Вам нужны.