通过 1 次 Copy ctor 调用进行绑定

发布于 2024-10-14 18:56:05 字数 1516 浏览 3 评论 0原文

我需要延迟调用一些带有参数的函数。接下来的测试代码:

#include <functional>
#include <boost/bind.hpp>
#include <boost/function.hpp>

struct test
{
    test()
    {
        std::cout << "ctor" << std::endl;
    }

    test& operator=(test const& t)
    {
        std::cout << "operator=" << std::endl;
        return *this;
    }

    test(test const& t)
    {
        std::cout << "copy ctor" << std::endl;
    }

    ~test()
    {
        std::cout << "dtor" << std::endl;
    }
};

int foo(test const & t)
{
    return 0;
}

int main()
{
    test t;
    boost::function<int()> f = boost::bind(foo, t);
    f();
    return 0;
}

输出是:

ctor
copy ctor
copy ctor
copy ctor
copy ctor
dtor
copy ctor
dtor
dtor
copy ctor
copy ctor
copy ctor
copy ctor
copy ctor
copy ctor
dtor
dtor
dtor
dtor
dtor
dtor
dtor
dtor
dtor

所以我们可以看到 copy ctor 调用了 11 次!

好的。将 boost::bind 更改为 std::bind:

int main()
{
    test t;
    boost::function<int()> f = std::bind(foo, t);
    f();
    return 0;
}

输出为:

ctor
copy ctor
copy ctor
copy ctor
dtor
copy ctor
copy ctor
copy ctor
copy ctor
copy ctor
copy ctor
dtor
dtor
dtor
dtor
dtor
dtor
dtor
dtor
dtor

Copy ctor 调用了 9 次。好的。如果将 boost::function 更改为 std::function copy ctor 将仅被调用 4 次。但这也是不好的行为。

是否可以通过 1 次复制构造函数调用来完成此操作? std::ref 是一个坏主意,因为它可以在其他线程等中调用。

抱歉我的英语不好:)谢谢。

I need deferred call of some function with arguments. Have next test code:

#include <functional>
#include <boost/bind.hpp>
#include <boost/function.hpp>

struct test
{
    test()
    {
        std::cout << "ctor" << std::endl;
    }

    test& operator=(test const& t)
    {
        std::cout << "operator=" << std::endl;
        return *this;
    }

    test(test const& t)
    {
        std::cout << "copy ctor" << std::endl;
    }

    ~test()
    {
        std::cout << "dtor" << std::endl;
    }
};

int foo(test const & t)
{
    return 0;
}

int main()
{
    test t;
    boost::function<int()> f = boost::bind(foo, t);
    f();
    return 0;
}

Output is:

ctor
copy ctor
copy ctor
copy ctor
copy ctor
dtor
copy ctor
dtor
dtor
copy ctor
copy ctor
copy ctor
copy ctor
copy ctor
copy ctor
dtor
dtor
dtor
dtor
dtor
dtor
dtor
dtor
dtor

So we can see what copy ctor called 11 times!!!

Ok. Change boost::bind to std::bind:

int main()
{
    test t;
    boost::function<int()> f = std::bind(foo, t);
    f();
    return 0;
}

Output is:

ctor
copy ctor
copy ctor
copy ctor
dtor
copy ctor
copy ctor
copy ctor
copy ctor
copy ctor
copy ctor
dtor
dtor
dtor
dtor
dtor
dtor
dtor
dtor
dtor

Copy ctor called 9 times. Ok. If change boost::function to std::function copy ctor will be called 4 times only. But it is bad behavior too.

Is it possible do this with 1 call of copy ctor? std::ref is a bad idea, because of it can invoke in other thread and etc.

Sorry for my bad English :) Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦初启 2024-10-21 18:56:05

使用 lambda 表达式。

int main()
{
    test t;
    std::function<int()> f = [=](){ foo(t); };
    f();
    return 0;
}

由于使用 lambda 非常方便等,绑定是极其多余的。另外,您确实在发布模式下编译并启用了所有优化,对吗?

您不会只得到一次复制构造函数调用,因为首先您必须生成一个函数对象,然后将该函数对象分配给 std::function 。也许它可能是 std::move 的?

由于您没有 lambda,甚至绑定也会生成三个副本,因此在这种情况下您只需手动编写自己的函数对象。

Use a lambda expression.

int main()
{
    test t;
    std::function<int()> f = [=](){ foo(t); };
    f();
    return 0;
}

Binding is exceedingly redundant due to the incredible ease etc of using lambdas. In addition, you did compile in Release mode with all optimizations on, right?

You won't get only one copy constructor call, because first you have to produce a function object, and then assign that function object into the std::function. Maybe it could be std::move'd?

Since you don't have lambdas and even binding produces three copies, you're just going to have to manually write your own function object in this case.

很酷又爱笑 2024-10-21 18:56:05

使用 lambda 是一个很好的答案。如果出于某种原因这对您不起作用,另一种可能性是将绑定的结果存储在 std::function: 之外的其他内容中:

decltype(std::bind(foo, t)) f = std::bind(foo, t);

或:

auto f = std::bind(foo, t);

在我的系统(clang/libc++)上,此输出:

ctor
copy ctor
dtor
dtor

尽管您的情况可能会有所不同。

Using lambdas is a good answer. If for whatever reason that doesn't work for you, another possibility is storing the result of the bind in something other than a std::function:

decltype(std::bind(foo, t)) f = std::bind(foo, t);

or:

auto f = std::bind(foo, t);

On my system (clang/libc++) this outputs:

ctor
copy ctor
dtor
dtor

Though your milage may vary.

日裸衫吸 2024-10-21 18:56:05

它确实在一定程度上取决于您要绑定的对象的生命周期。

假设该对象的生命周期包括仿函数的生命周期,只需

int main()
{
    test t;
    boost::function<int()> f( boost::bind(foo, boost::ref( t ) ) );
    f();
    return 0;
}

执行一次构造函数调用和一次析构函数调用即可。 :-)

干杯&呵呵,

It does depend a bit on the lifetime of the object that you want to bind.

Assuming that that object's lifetime includes the lifetime of the functor, just do

int main()
{
    test t;
    boost::function<int()> f( boost::bind(foo, boost::ref( t ) ) );
    f();
    return 0;
}

Yields one constructor call and one destructor call. :-)

Cheers & hth.,

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文