Binding with 1 call to ctor copy

I need a deferred call to some function with arguments. There is the following 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:

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 which copy of ctor is called 11 times !!!

Ok Edit boost :: bind to std :: bind:

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

Output:

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 times. OK. If change boost :: function to std :: function copy ctor will be called only 4 times. But this is also bad behavior.

Is it possible to do this with 1 call to copy ctor? std :: ref is a bad idea because it can be called on another thread, etc.

Sorry for my bad english :) Thanks.

+3
source share
3 answers

Use lambda expression.

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

- .. . , Release , ?

, , std:: function. , std::move 'd?

lambdas, , .

+1

lambdas - . - , , -, std:

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

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

(clang/lib++) :

ctor
copy ctor
dtor
dtor

.

+1

, .

, ,

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

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

Cheers and hth.,

0
source

Source: https://habr.com/ru/post/1788683/


All Articles