0

所以我在玩c ++ 11 Varidiacs,我想创建一个叫做CallClass的东西,基本上是一个扭曲函数的类,供以后调用,当所有变量都设置好时(真的我不知道它是否有用):

#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...);
        }
};

现在,当我尝试编译(使用 IDE:code::blocks 编译,配置为在 windows 上使用 MINGW)时,它会打印 Compiler:Segmentation Fault,有人有什么想法吗?

用法:

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;
}
4

1 回答 1

0

经过一番搜索后,我在某种程度上偶然发现了一个类似的问题。显然我解包元组的方式是一个问题,所以我决定使用不同的方法,如下所示:在此处输入链接描述

必须添加一些更改以满足我的需要:

变化:

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));
}

并更改了调用():

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

我可能会再做一些更改,例如将元组作为引用传递,并使结构成为我的类的一部分。

于 2016-10-27T10:55:19.643 回答