Я использовал Функтор Локи некоторое время, и недавно я спросил вопрос об этом (до сих пор без ответа …)
Мне сказали использовать std :: function, но я предпочитаю реализацию Functor от Loki, поскольку он также работает со всевозможными указателями в качестве параметров (например, std :: shared_ptr).
struct Toto
{
void foo( int param )
{
std::cout << "foo: " << param << std::endl;
}
};
int
main( int argc, const char** argv )
{
std::shared_ptr<Toto> ptr = std::make_shared<Toto>();
Loki::Functor<void, LOKI_TYPELIST_1(int)> func( ptr, &Toto::foo );
func(1);
}
Есть ли способ сделать это с помощью std :: function?
использование std::bind
,
auto func = std::bind(&Toto::foo, ptr, std::placeholders::_1);
Вот, func
будет выведен на тип, который был возвращен из std::bind
или если вам не нравится auto
вы можете использовать (и вы хотите использовать std::function
)
std::function<void(int)> func = std::bind(&Toto::foo,
ptr, std::placeholders::_1);
Вот std::function
будет построен из результата std::bind
,
ptr
будет скопирован в некоторый объект, возвращенный из std::bind
Однако вы можете использовать std::ref
/std::cref
если вы не хотите копий.
использование std::bind
,
struct Toto
{
void foo( int param )
{
std::cout << "foo: " << param << std::endl;
}
};
int main() {
std::shared_ptr<Toto> ptr = std::make_shared<Toto>();
std::function< void(int) > func( std::bind( &Toto::foo,
std::bind( [ptr] () { return ptr.get(); } ),
std::placeholders::_1
) );
func( 1 );
}
Изменить: внутренний bind
с лямбда-выражением на самом деле нет необходимости, но я просто оставлю это здесь как иллюстрацию более продвинутого использования.
Если вы не хотите использовать std::bind
можно использовать лямбда-функцию, в результате чего код будет еще меньше, и я лично нахожу его более интуитивным:
auto func = [&ptr](int p){ ptr->foo(p); };
или без auto
:
std::function<void(int)> func = [&ptr](int p){ ptr->foo(p); };
Но это работает только в том случае, если вызываемая функция является фиксированной (т.е. &Toto::foo
не был пройден динамически). Если нет, то все еще возможно с лямбда, но вам нужен немного другой синтаксис и std::bind
может быть более привлекательным снова.