0

So I was Playing around with c++11 Varidiacs, and I wanted to create a thing called CallClass, basically a class that warps a function, for later call,when all variables are set(truly I have No Idea If It can Be Useful):

#include <tuple>

template <typename OBJ,typename F,typename... VARGS>
class CallClass
{
    public:

        CallClass(OBJ& object,F callFunction)
        :_object(&object),_func(callFunction)
        { }

        CallClass(const CallClass& other)
        :_func_args(other._func_args)
        ,_object(other._object)
        ,_func(other._func)
        { }

        template <size_t INDEX>
        auto get(){ return std::get<INDEX>(_func_args); }

        template <size_t INDEX,typename T>
        void set(const T& val){ std::get<INDEX>(_func_args) = val; }

        template <size_t INDEX,typename T>
        void set(T&& val){ std::get<INDEX>(_func_args) = val; }

        auto Call()
        {
            //throws segmentation Fault Here
            return InnerCall<0>(_func_args);
        }

        virtual ~CallClass() {}

    protected:

    private:
        std::tuple<VARGS...> _func_args;
        OBJ* _object;
        F _func;

        template <size_t INDEX,typename... ARGS>
        auto InnerCall(std::tuple<VARGS...>& tup,ARGS... args)
        {
            auto arg = std::get<INDEX>(tup);

            return InnerCall<INDEX + 1>(tup,args...,arg);
        }

        template <size_t INDEX,VARGS...>
        auto InnerCall(std::tuple<VARGS...>& tup,VARGS... args)
        {
            return (_object->*_func)(args...);
        }
};

Now when I try to compile(compiling using IDE:code::blocks, configured to use MINGW On windows ), it prints Compiler:Segmentation Fault, anybody any Ideas?

Usage:

class obj{
public:
    obj(int a)
    :_a(a)
    { }

    virtual ~obj() {}

    int add(int b,int c){
        return _a + b + c;
    }

private:
    int _a;
};

int main(){
obj ob(6);
CallClass<obj,decltype(obj::add),int,int> callAdd(ob,obj::add);

    callAdd.set<0,int>(5);
    callAdd.set<1,int>(7);
    cout << "result is " << callAdd.Call() << endl;

    return 0;
}
MrHarmz
  • 23
  • 4

1 Answers1

0

After a Bit of a search i stumbled upon a similar issue, in a way. apparently the way I'm unpacking the tuple is an issue, so i decided to use a different approach as shown in: enter link description here

had to add a few changes to suit my needs:

changes:

namespace detail
{
    template <typename OBJ,typename F, typename Tuple, bool Done, int Total, int... N>
    struct call_impl
    {
        static auto call(OBJ& obj,F f, Tuple && t)
        {
            return call_impl<OBJ,F, Tuple, Total == 1 + sizeof...(N), Total, N..., sizeof...(N)>::call(obj,f, std::forward<Tuple>(t));
        }
    };

    template <typename OBJ,typename F, typename Tuple, int Total, int... N>
    struct call_impl<OBJ,F, Tuple, true, Total, N...>
    {
        static auto call(OBJ& obj,F f, Tuple && t)
        {
            return (obj.*f)(std::get<N>(std::forward<Tuple>(t))...);
        }
    };
}

// user invokes this
template <typename OBJ,typename F, typename Tuple>
auto call(OBJ& obj,F f, Tuple && t)
{
    typedef typename std::decay<Tuple>::type ttype;
    return detail::call_impl<OBJ,F, Tuple, 0 == std::tuple_size<ttype>::value, std::tuple_size<ttype>::value>::call(obj,f, std::forward<Tuple>(t));
}

and changed Call():

auto Call()
{
    std::tuple<VARGS...> func_args = _func_args;
    return call(*_object,_func, std::move(func_args));
}

I will probably make a few more changes, like passing the tuple as a reference, and making the structs a part of my class.

Community
  • 1
  • 1
MrHarmz
  • 23
  • 4