std::函数和shared_ptr

问题描述 投票:0回答:3

我已经使用 Loki's Functor 一段时间了,最近我问了一个关于它的问题(仍然没有答案......) 我被告知要使用 std::function,但我更喜欢 Loki 的 Functor 实现,因为它也可以使用各种指针作为参数(例如 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 做到这一点?

c++ std-function c++-loki
3个回答
6
投票

使用

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


2
投票

如果你不想使用

std::bind
,一个选择是使用 lambda 函数,这样代码会更小,我个人觉得它更直观:

auto func = [&ptr](int p){ ptr->foo(p); };

或没有

auto
:

std::function<void(int)> func = [&ptr](int p){ ptr->foo(p); };

但这仅在要调用的函数是固定的情况下才有效(即

&Toto::foo
不是动态传递的)。如果没有,仍然可以使用 lambda,但您需要稍微不同的语法,并且
std::bind
可能会再次更具吸引力。


1
投票

使用

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 );
}

现场演示。

编辑:带有 lambda 表达式的内部

bind
实际上是不必要的,但我将其留在这里作为更高级用法的说明。

© www.soinside.com 2019 - 2024. All rights reserved.