function源码

std::function是一个可变参类模板,是一个通用的函数包装器(Polymorphic function wrapper)。std::function的实例可以存储、复制和调用任何可复制构造的可调用目标,包括普通函数、成员函数、类对象(重载了operator()的类的对象)、Lambda表达式等。是对C++现有的可调用实体的一种类型安全的包裹(相比而言,函数指针这种可调用实体,是类型不安全的)。std::function中存储的可调用对象被称之为std::function的目标。若std::function中不含目标,调用不含目标的std::function会抛出std::bad_function_call 异常。

实现一个简单的function



#include <exception>

class bad_function_call : public std::exception
{
	virtual const char* what() const noexcept
	{
		return "bad function call";
	}
};

#include <cstddef>
#include <utility>
#include <memory>

//定义空模板类
template <typename Fun>
class MyFunction;

//模板特化,特化的类型的为Ret(Args...)函数类对象(也就是实现了()操作符的类对象)
//Ret返回值类型,Args可变参数
template <typename Ret, typename ... Args>
class MyFunction<Ret(Args...)>
{
private:
	//存储可执行对象的基类
	class function_control_block_base
	{
		friend class MyFunction;
	private:
		//深拷贝
		virtual function_control_block_base* clone() const = 0;
		//调用该可执行对象
		virtual Ret invoke(Args ... args) const = 0;
		virtual ~function_control_block_base() = default;
	};
	
	//可执行对象的实现类
	template <typename Fun>
	class function_control_block : function_control_block_base
	{
		friend class MyFunction;
	private:
		Fun fun; //将可执行类型保存

		function_control_block(const function_control_block&) = default;
		
		//构造函数,Fun可以是int(int) 是函数类型,也可以是 int(*)(int) 
		explicit function_control_block(Fun&& fun) : fun(std::forward<Fun>(fun))
		{
		}

		virtual function_control_block_base* clone() const
		{
			return new function_control_block(*this);
		}
		
		//调用可执行类型
		virtual Ret invoke(Args ... args) const
		{
			return fun(std::forward<Args>(args)...);
		}
	};

	function_control_block_base* control_block; //执行对象指针

public:

	MyFunction() : control_block(NULL)
	{
	}

	MyFunction(const MyFunction& src) : control_block(src.control_block->clone())
	{
	}

	MyFunction(MyFunction&& src) : control_block(src.control_block)
	{
		src.control_block = NULL;
	}

	//构造函数,Fun可以是int(int) 是函数类型,也可以是 int(*)(int) 
	template <typename Fun>
	MyFunction(Fun&& fun) : control_block(new function_control_block<Fun>(std::forward<Fun>(fun)))
	{
	}

	~MyFunction()
	{
		delete control_block;
	}

	void swap(MyFunction& ano)
	{
		std::swap(this->control_block, ano.control_block);
	}

	operator bool() const
	{
		return this->control_block != NULL;
	}
	
	//重载了operator()
	Ret operator()(Args ... args) const
	{
		if (static_cast<bool>(*this) == false) {
			throw bad_function_call();
		}
		return this->control_block->invoke(std::forward<Args>(args)...);
	}
};


#include <iostream>

int add(int x)
{
	return x + 1;
}

int add2(int x, int y)
{
	return x + y;
}

#include <functional> // std::bind

int main()
{

	::MyFunction<int(int)> f = add;
	std::cout << f(3) << std::endl;

	int out = 7;
	auto lam = [&out](int x) {
		out += x;
		return out;
	};
	::MyFunction<int(int)> f2 = lam;

	std::cout << f2(3) << std::endl;
	std::cout << out << std::endl;

	::MyFunction<int(int)> f3 = std::bind(add2, 7, std::placeholders::_1);
	std::cout << f3(7) << std::endl;

	std::function<void(void)> test;

}

VS源码

template <class _Ty1, class _Ty2, bool = is_empty_v<_Ty1> && !is_final_v<_Ty1>>
class _Compressed_pair final : private _Ty1 { // store a pair of values, deriving from empty first
public:
    _Ty2 _Myval2;

    using _Mybase = _Ty1; // for visualization

    template <class... _Other2>
    constexpr explicit _Compressed_pair(_Zero_then_variadic_args_t, _Other2&&... _Val2) noexcept(
        conjunction_v<is_nothrow_default_constructible<_Ty1>, is_nothrow_constructible<_Ty2, _Other2...>>)
        : _Ty1(), _Myval2(_STD forward<_Other2>(_Val2)...) {}

    template <class _Other1, class... _Other2>
    constexpr _Compressed_pair(_One_then_variadic_args_t, _Other1&& _Val1, _Other2&&... _Val2) noexcept(
        conjunction_v<is_nothrow_constructible<_Ty1, _Other1>, is_nothrow_constructible<_Ty2, _Other2...>>)
        : _Ty1(_STD forward<_Other1>(_Val1)), _Myval2(_STD forward<_Other2>(_Val2)...) {}

    constexpr _Ty1& _Get_first() noexcept {
        return *this;
    }

    constexpr const _Ty1& _Get_first() const noexcept {
        return *this;
    }
};


//最顶层的基础模板类,定义了函数对象在实例复制、转移上的纯虚接口,
//如Copy、Move等。同时定义了函数调用的虚接口_Do_call。这些纯虚接口要求在子类中实现。
//保存了其关联函数的类型信息,返回值类型Rx,各入参类型列表_Types,这些模板形参在模板类的实现中能够获取到。
template <class _Rx, class... _Types>
class __declspec(novtable) _Func_base { // abstract base for implementation types
public:
    virtual _Func_base* _Copy(void*) const = 0;
    virtual _Func_base* _Move(void*) noexcept = 0;
    virtual _Rx _Do_call(_Types&&...) = 0;
    virtual const type_info& _Target_type() const noexcept = 0;
    virtual void _Delete_this(bool) noexcept = 0;

    _Func_base() = default;
    _Func_base(const _Func_base&) = delete;
    _Func_base& operator=(const _Func_base&) = delete;
    // dtor non-virtual due to _Delete_this()

private:
    virtual const void* _Get() const noexcept = 0;
};




//模板子类,实现了_Func_base定义的所有虚接口。其声明有所不同:

//_Callable可调用对对象类型,可是函数指针,也可以是实现operator()操作符的可调用实体。
template <class _Callable, class _Rx, class... _Types>
class _Func_impl_no_alloc final : public _Func_base<_Rx, _Types...> {
    // derived class for specific implementation types that don't use allocators
public:
    using _Mybase = _Func_base<_Rx, _Types...>;
    using _Nothrow_move = is_nothrow_move_constructible<_Callable>;

    //构造函数
    template <class _Other, enable_if_t<!is_same_v<_Func_impl_no_alloc, decay_t<_Other>>, int> = 0>
    explicit _Func_impl_no_alloc(_Other&& _Val) : _Callee(_STD forward<_Other>(_Val)) {}

    // dtor non-virtual due to _Delete_this()

private:
    virtual _Mybase* _Copy(void* _Where) const override {
        if constexpr (_Is_large<_Func_impl_no_alloc>) {
            (void)_Where; // TRANSITION, DevCom-1004719
            return _Global_new<_Func_impl_no_alloc>(_Callee);
        }
        else {
            return ::new (_Where) _Func_impl_no_alloc(_Callee);
        }
    }

    virtual _Mybase* _Move(void* _Where) noexcept override {
        if constexpr (_Is_large<_Func_impl_no_alloc>) {
            (void)_Where; // TRANSITION, DevCom-1004719
            return nullptr;
        }
        else {
            return ::new (_Where) _Func_impl_no_alloc(_STD move(_Callee));
        }
    }

    virtual _Rx _Do_call(_Types&&... _Args) override { // call wrapped function
        return _Invoker_ret<_Rx>::_Call(_Callee, _STD forward<_Types>(_Args)...);
    }

    virtual const type_info& _Target_type() const noexcept override {
#if _HAS_STATIC_RTTI
        return typeid(_Callable);
#else // _HAS_STATIC_RTTI
        _CSTD abort();
#endif // _HAS_STATIC_RTTI
    }

    virtual const void* _Get() const noexcept override {
        return _STD addressof(_Callee);
    }

    virtual void _Delete_this(bool _Dealloc) noexcept override { // destroy self
        this->~_Func_impl_no_alloc();
        if (_Dealloc) {
            _Deallocate<alignof(_Func_impl_no_alloc)>(this, sizeof(_Func_impl_no_alloc));
        }
    }

    _Callable _Callee;
};

_Alloc内存分配器,负责_Func_impl对象创建时做内存分配。allocator是STL中非常重要的部分,如容器中元素所用内存空间的分配都是由allocator负责,其对内存获取的方式做了抽象。
template <class _Callable, class _Alloc, class _Rx, class... _Types>
class _Func_impl final : public _Func_base<_Rx, _Types...> {
    // derived class for specific implementation types that use allocators
public:
    using _Mybase = _Func_base<_Rx, _Types...>;
    using _Myalty = _Rebind_alloc_t<_Alloc, _Func_impl>;
    using _Myalty_traits = allocator_traits<_Myalty>;
    using _Nothrow_move = is_nothrow_move_constructible<_Callable>;

    //该成员是一个pair类型,保存内存分配器及可调用类型的对象。_Compressed_pair为类模板,可适配保存任意类型的可调用对象。_Func_impl仅有如下pubic的构造函数,在构造函数中初始化其Pair成员,何时调用该构造函数在后面说明。
    template <class _Other1, class _Other2>
    _Func_impl(_Other1&& _Val, _Other2&& _Ax)
        : _Mypair(_One_then_variadic_args_t{}, _STD forward<_Other2>(_Ax), _STD forward<_Other1>(_Val)) {}

    // dtor non-virtual due to _Delete_this()

private:
    virtual _Mybase* _Copy(void* _Where) const override {
        auto& _Myax = _Mypair._Get_first();
        if constexpr (_Is_large<_Func_impl>) {
            _Myalty _Rebound(_Myax);
            _Alloc_construct_ptr<_Myalty> _Constructor{ _Rebound };
            _Constructor._Allocate();
            _Construct_in_place(*_Constructor._Ptr, _Mypair._Myval2, _Myax);
            return _Constructor._Release();
        }
        else {
            const auto _Ptr = static_cast<_Func_impl*>(_Where);
            _Construct_in_place(*_Ptr, _Mypair._Myval2, _Myax);
            return _Ptr;
        }
    }

    virtual _Mybase* _Move(void* _Where) noexcept override {
        if constexpr (_Is_large<_Func_impl>) {
            return nullptr;
        }
        else {
            const auto _Ptr = static_cast<_Func_impl*>(_Where);
            _Construct_in_place(*_Ptr, _STD move(_Mypair._Myval2), _STD move(_Mypair._Get_first()));
            return _Ptr;
        }
    }

    virtual _Rx _Do_call(_Types&&... _Args) override { // call wrapped function
        return _Invoker_ret<_Rx>::_Call(_Mypair._Myval2, _STD forward<_Types>(_Args)...);
    }


    virtual const void* _Get() const noexcept override {
        return _STD addressof(_Mypair._Myval2);
    }

    virtual void _Delete_this(bool _Deallocate) noexcept override { // destroy self
        _Myalty _Al(_Mypair._Get_first());
        _Destroy_in_place(*this);
        if (_Deallocate) {
            _Deallocate_plain(_Al, this);
        }
    }

    _Compressed_pair<_Alloc, _Callable> _Mypair;
};

template <class... _Types>
struct _Arg_types {};

template <class _Ty1>
struct _Arg_types<_Ty1> {
    typedef _Ty1 argument_type;
};

template <class _Ty1, class _Ty2>
struct _Arg_types<_Ty1, _Ty2> {
    typedef _Ty1 first_argument_type;
    typedef _Ty2 second_argument_type;
};

//_Func_class是最外层的类,_Storage用于保存了_Func_impl对象。
//内存上使用union,与_Func_impl的复制转移的优化策略相匹配:小内存对象时用&_MyStorage作为预分配内存,否则由分配器动态分配,而且将创建返回的对象地址记录在_Ptrs[_Num_ptrs-1]中。
//而且注意到_Func_class的模板形参中并没有_Callable和_Alloc,说明该两个形参是在_Func_impl的创建(或拷贝)处通过函数模板形参传入的。关键代码如下:

template <class _Ret, class... _Types>
class _Func_class : public _Arg_types<_Types...> {
public:
    using result_type = _Ret;

    using _Ptrt = _Func_base<_Ret, _Types...>;

    _Func_class() noexcept {
        _Set(nullptr);
    }

    _Ret operator()(_Types... _Args) const {
        if (_Empty()) {
            _Xbad_function_call();
        }
        const auto _Impl = _Getimpl();
        return _Impl->_Do_call(_STD forward<_Types>(_Args)...);
    }

    ~_Func_class() noexcept {
        _Tidy();
    }

protected:
    template <class _Fx, class _Function>
    using _Enable_if_callable_t =
        enable_if_t<conjunction_v<negation<is_same<decay_t<_Fx>, _Function>>, _Is_invocable_r<_Ret, _Fx, _Types...>>,
        int>;

    bool _Empty() const noexcept {
        return !_Getimpl();
    }

    void _Reset_copy(const _Func_class& _Right) { // copy _Right's stored object
        if (!_Right._Empty()) {
            _Set(_Right._Getimpl()->_Copy(&_Mystorage));
        }
    }

    void _Reset_move(_Func_class&& _Right) noexcept { // move _Right's stored object
        if (!_Right._Empty()) {
            if (_Right._Local()) { // move and tidy
                _Set(_Right._Getimpl()->_Move(&_Mystorage));
                _Right._Tidy();
            }
            else { // steal from _Right
                _Set(_Right._Getimpl());
                _Right._Set(nullptr);
            }
        }
    }
	
	//一般由这里构造
    template <class _Fx>
    void _Reset(_Fx&& _Val) { // store copy of _Val
        if (!_Test_callable(_Val)) { // null member pointer/function pointer/std::function
            return; // already empty
        }

        using _Impl = _Func_impl_no_alloc<decay_t<_Fx>, _Ret, _Types...>;
        if constexpr (_Is_large<_Impl>) {
            // dynamically allocate _Val
            _Set(_Global_new<_Impl>(_STD forward<_Fx>(_Val)));
        }
        else { //直接使用当前内存块作为执行对象的地址
            // store _Val in-situ
            _Set(::new (static_cast<void*>(&_Mystorage)) _Impl(_STD forward<_Fx>(_Val)));
        }
    }


    void _Tidy() noexcept {
        if (!_Empty()) { // destroy callable object and maybe delete it
            _Getimpl()->_Delete_this(!_Local());
            _Set(nullptr);
        }
    }

    void _Swap(_Func_class& _Right) noexcept { // swap contents with contents of _Right
        if (!_Local() && !_Right._Local()) { // just swap pointers
            _Ptrt* _Temp = _Getimpl();
            _Set(_Right._Getimpl());
            _Right._Set(_Temp);
        }
        else { // do three-way move
            _Func_class _Temp;
            _Temp._Reset_move(_STD move(*this));
            _Reset_move(_STD move(_Right));
            _Right._Reset_move(_STD move(_Temp));
        }
    }


private:
    bool _Local() const noexcept { // test for locally stored copy of object
        return _Getimpl() == static_cast<const void*>(&_Mystorage);
    }

    enum { _EEN_IMPL = _Small_object_num_ptrs - 1 }; // helper for expression evaluator
    _Ptrt* _Getimpl() const noexcept { // get pointer to object
        return _Mystorage._Ptrs[_Small_object_num_ptrs - 1];
    }

    void _Set(_Ptrt* _Ptr) noexcept { // store pointer to object
        _Mystorage._Ptrs[_Small_object_num_ptrs - 1] = _Ptr;
    }


    //_Storage用于保存了_Func_impl对象。内存上使用union,与_Func_impl的复制转移的优化策略相匹配:
    //小内存对象时用&_MyStorage作为预分配内存,否则由分配器动态分配,而且将创建返回的对象地址记录在_Ptrs[_Num_ptrs-1]中。
    union _Storage { // storage for small objects (basic_string is small)
            using max_align_t = double; // most aligned type
        max_align_t _Dummy1; // for maximum alignment     
                   
                 //constexpr int _Small_object_num_ptrs = 6 + 16 / sizeof(void*); 
                 // std::function 和 std::any 指针的大小(构建调试时大约比 std::string 大 3 个指针)
                //constexpr size_t _Space_size = (_Small_object_num_ptrs - 1) * sizeof(void*);
        char _Dummy2[_Space_size]; // to permit aliasing


        _Ptrt* _Ptrs[_Small_object_num_ptrs]; // _Ptrs[_Small_object_num_ptrs - 1] is reserved
    };

    _Storage _Mystorage;
};


template <class _Tx>
struct _Get_function_impl {
    static_assert(_Always_false<_Tx>, "std::function does not accept non-function types as template arguments.");
};

template <class _Ret, class... _Types>
struct _Get_function_impl<_Ret __cdecl(_Types...)> 
{
    using type = _Func_class<_Ret, _Types...>; 
};  

template <class _Ret, class... _Types> 
struct _Get_function_impl<_Ret __fastcall(_Types...)> 
{ using type = _Func_class<_Ret, _Types...>; }; 

template <class _Ret, class... _Types> 
struct _Get_function_impl<_Ret __stdcall(_Types...)> 
{ using type = _Func_class<_Ret, _Types...>; }; 

template <class _Ret, class... _Types> 
struct _Get_function_impl<_Ret __vectorcall(_Types...)> 
{ using type = _Func_class<_Ret, _Types...>; };



template <class _Fty>
class function;

//通常fuction的使用不会直接指定返回值和形参列表,而是function<Ret(arg1, arg2, …)>的方式,而_Func_class的模板形参中又是Ret和_Types…,如何转化?
//这其实就是_Get_function_impl的作用,通过模板偏特化,借助编译器的推导能力,从中分离出Ret和_Types…,构建_Func_class,通
//俗讲,“返回值”就是_Func_class<_Ret, _Types…>,所以function是继承自_Func_class的。紧接着看一个funciton的构造函数:
template <class _Fty>
class function : public _Get_function_impl<_Fty>::type { // wrapper for callable objects
private:
    using _Mybase = typename _Get_function_impl<_Fty>::type;

public:
    function() noexcept {}

    function(nullptr_t) noexcept {}

    function(const function& _Right) {
        this->_Reset_copy(_Right);
    }

    //构造其实就是调用基类的_Reset
    function(_Fx _Func) {
        this->_Reset(_STD move(_Func));
    }



    function& operator=(const function& _Right) {
        function(_Right).swap(*this);
        return *this;
    }

    function(function&& _Right) noexcept {
        this->_Reset_move(_STD move(_Right));
    }


    function& operator=(function&& _Right) noexcept /* strengthened */ {
        if (this != _STD addressof(_Right)) {
            this->_Tidy();
            this->_Reset_move(_STD move(_Right));
        }
        return *this;
    }


    function& operator=(_Fx&& _Func) {
        function(_STD forward<_Fx>(_Func)).swap(*this);
        return *this;
    }



    function& operator=(nullptr_t) noexcept {
        this->_Tidy();
        return *this;
    }

    template <class _Fx>
    function& operator=(reference_wrapper<_Fx> _Func) noexcept {
        this->_Tidy();
        this->_Reset(_Func);
        return *this;
    }

    void swap(function& _Right) noexcept {
        this->_Swap(_Right);
    }

    explicit operator bool() const noexcept {
        return !this->_Empty();
    }


    const type_info& target_type() const noexcept = delete; // requires static RTTI

    template <class _Fx>
    _Fx* target() noexcept = delete; // requires static RTTI

    template <class _Fx>
    const _Fx* target() const noexcept = delete; // requires static RTTI

};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值