1
\$\begingroup\$

I've decided to make an implementation of the C++11 class function. I was checking that I have done everything correctly and have not missed anything:

template < typename > class function;

template < typename _Ret, typename... _Args > class function<_Ret(_Args...)>
{
public:
    typedef _Ret result_type;
    typedef function<result_type(_Args...)> _Myt;
    typedef result_type(*pointer)(_Args...);

    function()
        : _f_ptr(nullptr)
    {
    }

    template < typename _Fn_Ty > function(_Fn_Ty &&_Fn)
        : _f_ptr(reinterpret_cast<pointer>(_Fn))
    {
    }

    function(pointer &&_Fn)
        : _f_ptr(_Fn)
    {
    }

    function(const _Myt &_Rhs)
        : _f_ptr(_Rhs.f_ptr)
    {
    }

    function(_Myt &&_Rhs)
        : _f_ptr(_Rhs.f_ptr)
    {
    }

    ~function()
    {
    }

    _Myt &assign(pointer &&_Fn)
    {
        _f_ptr = _Fn;
        return *this;
    }

    _Myt &operator=(pointer &&_Fn)
    {
        return assign(_Fn);
    }

    template < typename _Fn_Ty > _Myt &assign(_Fn_Ty &&_Fn)
    {
        _f_ptr = reinterpret_cast<pointer>(_Fn);
        return *this;
    }

    template < typename _Fn_Ty > _Myt &operator=(_Fn_Ty &&_Fn)
    {
        return assign<_Fn_Ty>(_Fn);
    }

    result_type operator()(_Args... _Arguments)
    {
        if (_f_ptr == nullptr)
        {
            throw std::exception("nullptr found instead of function");
        }
        return _f_ptr(_Arguments...);
    }

    pointer &ptr() const
    {
        return _f_ptr;
    }

    operator pointer &() const
{
    return _f_ptr;
}
private:
    pointer _f_ptr;
};
\$\endgroup\$
  • 3
    \$\begingroup\$ Maybe you could provide a compilable online example where you use your function to store (and then run) a function pointer, a pointer-to-member-function, a stateless lambda, a stateful lambda and a bind expression? Look here for inspiration. \$\endgroup\$ – TemplateRex Mar 4 '14 at 17:42
  • 4
    \$\begingroup\$ In every one of your questions you use reserved identifiers and some people have commented on it yet you still do it. Is the habit too strong to break? \$\endgroup\$ – Rapptz Mar 4 '14 at 19:38
  • \$\begingroup\$ @Rapptz - I've kind of got used to it even though it is a bad habit. Woops :O \$\endgroup\$ – Joseph Mar 4 '14 at 21:39
  • 3
    \$\begingroup\$ another recurring theme in your questions here: you like reimplementing Standard Library functionality, which is a great learning tool. But it would be better if you first carefully checked things like all member functions and their signatures against the Standard before posting Code to Review. That, better naming and a few test cases to show that your implementation has at least a chance of being correct, would go a long way for people to review your code more carefully. That's why online compilers exist! \$\endgroup\$ – TemplateRex Mar 4 '14 at 21:43
  • 1
    \$\begingroup\$ This doesn't compile when testing with basic lambdas, like function<int(int)> f = [](int i) -> int { return i * 2; }; \$\endgroup\$ – Yuushi Mar 5 '14 at 0:21
4
\$\begingroup\$

Your code has no chance of working, because the only non-static data member of your function<void(void)> is a single pointer of type void (*)(void). There's no room to store any other kind of functor.

In other words, you've implemented the concept of "function pointer wrapped in a struct", but you haven't implemented anything like std::function yet.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.