LINUX.ORG.RU

История изменений

Исправление fsb4000, (текущая версия) :

Да, так как reference_wrapper нужно чтобы наша лямбда жила, он не всегда подходит…

Вот что нашёл в интернете:

#include <iostream>
#include <functional>
#include <memory>
#include <utility>
#include <future>
#include <iostream>
#include <type_traits>
#include <cstddef>

template <typename F>
class shared_function : public std::shared_ptr<F> {
public:
	using std::shared_ptr<F>::shared_ptr;

	template <typename ...Args>
	auto operator()(Args&&...args) const
		-> typename std::result_of<F(Args...)>::type
	{
		return (*(this->get()))(std::forward<Args>(args)...);
	}
};

template <typename F>
shared_function<F> make_shared_fn(F&& f)
{
    return shared_function<F>{
		std::make_unique<typename std::remove_reference<F>::type>( std::forward<F>(f))
	};
}

std::function<void()> test() 
{
    std::unique_ptr<int> p = std::make_unique<int>(92);
    auto fn_once = [p = std::move(p)]() mutable {
        std::cout << *p << std::endl;
        p.release();
    };
    return make_shared_fn(std::move(fn_once));
}

void exec(const std::function<void()>& f) {
    f();
}
int main() 
{
    exec(test());
    std::unique_ptr<int> p = std::make_unique<int>(92);
    exec(make_shared_fn([p = std::move(p)]() mutable {
		std::cout << *p << std::endl;
		p.release();
	}));
}

Я не до конца ещё понимаю make_shared_fn, но она владеет лямбдой, и теперь нам не важно время жизни оригинальной лямбды в отличие от std::reference_wrapper

Исправление fsb4000, :

Да, так как reference_wrapper нужно чтобы наша лямбда жила, он не всегда подходит…

Вот что нашёл в интернете:

#include <iostream>
#include <functional>
#include <memory>
#include <utility>
#include <future>
#include <iostream>
#include <type_traits>
#include <cstddef>

template <typename F>
class shared_function : public std::shared_ptr<F> {
public:
	using std::shared_ptr<F>::shared_ptr;

	template <typename ...Args>
	auto operator()(Args&&...args) const
		-> typename std::result_of<F(Args...)>::type
	{
		return (*(this->get()))(std::forward<Args>(args)...);
	}
};

template <typename F>
shared_function<F> make_shared_fn(F&& f)
{
    return shared_function<F>{
		std::make_shared<typename std::remove_reference<F>::type>( std::forward<F>(f))
	};
}

std::function<void()> test() 
{
    std::unique_ptr<int> p = std::make_unique<int>(92);
    auto fn_once = [p = std::move(p)]() mutable {
        std::cout << *p << std::endl;
        p.release();
    };
    return make_shared_fn(std::move(fn_once));
}

void exec(const std::function<void()>& f) {
    f();
}
int main() 
{
    exec(test());
    std::unique_ptr<int> p = std::make_unique<int>(92);
    exec(make_shared_fn([p = std::move(p)]() mutable {
		std::cout << *p << std::endl;
		p.release();
	}));
}

Я не до конца ещё понимаю make_shared_fn, но она владеет лямбдой, и теперь нам не важно время жизни оригинальной лямбды в отличие от std::reference_wrapper

Исправление fsb4000, :

Да, так как reference_wrapper нужно чтобы наша лямбда жила, он не всегда подходит…

Вот что нашёл в интернете:

#include <iostream>
#include <functional>
#include <memory>
#include <utility>
#include <future>
#include <iostream>
#include <type_traits>
#include <cstddef>

template <typename F>
class shared_function : public std::shared_ptr<F> {
public:
	using std::shared_ptr<F>::shared_ptr;

	template <typename ...Args>
	auto operator()(Args&&...args) const
		-> typename std::result_of<F(Args...)>::type
	{
		return (*(this->get()))(std::forward<Args>(args)...);
	}
};

template <typename F>
shared_function<F> make_shared_fn(F&& f)
{
    return shared_function<F>{
		std::make_shared<typename std::remove_reference<F>::type>( std::forward<F>(f))
	};
}

std::function<void()> test() 
{
    std::unique_ptr<int> p = std::make_unique<int>(92);
    auto fn_once = [p = std::move(p)]() mutable {
        std::cout << *p << std::endl;
        p.release();
    };
    return make_shared_fn(std::move(fn_once));
}

void exec(const std::function<void()>& f) {
    f();
}
int main() 
{
    exec(test());
}

Я не до конца ещё понимаю make_shared_fn, но она владеет лямбдой, и теперь нам не важно время жизни оригинальной лямбды в отличие от std::reference_wrapper

Исправление fsb4000, :

Да, так как reference_wrapper нужно чтобы наша лямбда жила, он не всегда подходит…

Вот что нашёл в интернете:

#include <iostream>
#include <functional>
#include <memory>
#include <utility>
#include <future>
#include <iostream>
#include <type_traits>
#include <cstddef>

template <typename F>
class shared_function : public std::shared_ptr<F> {
public:
	using std::shared_ptr<F>::shared_ptr;

	template <typename ...Args>
	auto operator()(Args&&...args) const
		-> typename std::result_of<F(Args...)>::type
	{
		return (*(this->get()))(std::forward<Args>(args)...);
	}
};

template <typename F>
shared_function<F> make_shared_fn(F&& f)
{
	return shared_function<F>{
		new typename std::remove_reference<F>::type{ std::forward<F>(f) }};
}

std::function<void()> test() 
{
    std::unique_ptr<int> p = std::make_unique<int>(92);
    auto fn_once = [p = std::move(p)]() mutable {
        std::cout << *p << std::endl;
        p.release();
    };
    return make_shared_fn(std::move(fn_once));
}

void exec(const std::function<void()>& f) {
    f();
}
int main() 
{
    exec(test());
}

Я не до конца ещё понимаю make_shared_fn, но она владеет лямбдой, и теперь нам не важно время жизни оригинальной лямбды в отличие от std::reference_wrapper

Исходная версия fsb4000, :

Да, так как reference_wrapper нужно чтобы наша лямбда жила, он не всегда подходит…

Вот что нашёл в интернете:

#include <iostream>
#include <functional>
#include <memory>
#include <utility>
#include <future>
#include <iostream>
#include <type_traits>
#include <cstddef>

template <typename F>
class shared_function : public std::shared_ptr<F> {
public:
	using std::shared_ptr<F>::shared_ptr;

	template <typename ...Args>
	auto operator()(Args&&...args) const
		-> typename std::result_of<F(Args...)>::type
	{
		return (*(this->get()))(std::forward<Args>(args)...);
	}
};

template <typename F>
shared_function<F> make_shared_fn(F&& f)
{
	return shared_function<F>{
		new typename std::remove_reference<F>::type{ std::forward<F>(f) }};
}

std::function<void()> test() {
	std::unique_ptr<int> p = std::make_unique<int>(92);
	auto fn_once = [p = std::move(p)]() mutable {
		std::cout << *p << std::endl;
		p.release();
	};
	return make_shared_fn(std::move(fn_once));
}

void exec(const std::function<void()>& f) {
	f();
}
int main() 
{
	exec(test());
}

Я не до конца ещё понимаю make_shared_fn, но она владеет лямбдой, и теперь нам не важно время жизни оригинальной лямбды в отличие от std::reference_wrapper