模板函数接受调用函子与X参数(Template function accepting callabl

2019-10-18 03:31发布

我正在写运行在飞编译用户编写的C代码托管C ++程序。 这是绝对至关重要的某些典型的例外是从C代码捕获和处理/忽略。 要做到这一点,我打电话从结构化异常处理块中的C代码。 由于该块(与在那里的,从称呼)的性质和语义,我已经分离的实际调用它自己的功能:

    template <typename ret_type, class func>
        static ret_type Cstate::RunProtectedCode(func function) {
            ret_type ret = 0;
            __try {
                ret = function();
            }
            __except(ExceptionHandler(GetExceptionCode(), ExceptionStatus::CSubsystem)) {
                fprintf(stderr, "First chance exception in C-code.\n");
            }
            return ret;
        }

这很好地工作,因为它应该像这样:

        RunProtectedCode<int>(entry);

但是,它可以塑造这个,所以我可以调用函数与可变数量的参数 - 也许通过一些利用外来函子的(唯一的要求是很明显,它不能有析构函数)? 我使用的是MSVC ++ 2010。

Answer 1:

如果你可以使用C ++ 11你可以用可变参数tempaltes实现这一目标。

template <typename ret_type, class func, typename... Args>
    static ret_type Cstate::RunProtectedCode(func function, Args&&... args) {
        ret_type ret = 0;
        __try {
            ret = function(std::forward<Args>(args)...);
        }
        __except(ExceptionHandler(GetExceptionCode(), ExceptionStatus::CSubsystem)) {
            fprintf(stderr, "First chance exception in C-code.\n");
        }
        return ret;
    }

你可以这样调用它

RunProtectedCode<int>(entry2, 1, 2);
RunProtectedCode<int>(entry3, 1, "a", 3);

您可以通过使用的std ::函数,而不是把它简化( )。

template <class func, typename... Args>
    static 
    typename func::result_type Cstate::RunProtectedCode(func function, Args&&... args) {
        typename func::result_type ret = typename func::result_type();
        __try {
            ret = function(std::forward<Args>(args)...);
        }
        __except(ExceptionHandler(GetExceptionCode(), ExceptionStatus::CSubsystem)) {
            fprintf(stderr, "First chance exception in C-code.\n");
        }
        return ret;
    }

你可以这样调用它

std::function<int(int,int,int)> entry_f = entry;
RunProtectedCode(entry_f,1,2,3);


Answer 2:

可以将所有的参数绑定到你的功能使其成为有效0元仿函数,例如使用std::bind (在VC2010可用)或boost::bind (我喜欢这一个,因为VC实现包含破碎std::cref )。 结合可以在重载函数来完成传递之前RunProtectedCode ,比如像这样:

template<typename R>
R(*f)() wrap(R(*f)())
{
    return f;
}

template<typename R, typename A>
boost::function<R(A)> wrap(R(*f)(), A a)
{
    return boost::bind(f, a);
}

template<typename R, typename A1, typename A2>
boost::function<R(A1, A2)> wrap(R(*f)(), A1 a1, A2 a2)
{
    return boost::bind(f, a1, a2);
}


文章来源: Template function accepting callable functors with X parameters