模板专业化崩溃

时间:2016-02-24 14:22:17

标签: c++ templates c++11 lambda c++14

SOERS,

我正在使用(尝试使用)模板特化,整数序列和元组的组合来使用可变参数模板从中检索参数 API,取决于方法签名。我的程序在执行执行此操作的函数时崩溃。任何人都可以给我一个暗示,为什么会发生这种情况?我试图绑定签名int(*)(std::string)的功能。 这是使用函数的位置/创建用于绑定的lambda的位置:

template<typename T_Return, typename ... T_Params>
void bindFunction(T_Return(*function_item)(T_Params ...))
{
    std::function<T_Return(T_Params ...)> proxy_func(function_item);
    duk_function_t func = [proxy_func] (duk_context* ctx) mutable ->   duk_ret_t {
        const int n_Args = sizeof...(T_Params);
        if(duk_get_top(ctx)==n_Args)
        {
            if(std::is_same<T_Return, void>::value)
            {
                detail::duk_get_args<T_Return, T_Params ...>(ctx, proxy_func);
                return 0;
            }
            else
            {
                detail::duk_return(ctx, detail::duk_get_args(ctx, proxy_func)); //Program crashes in this line
                return 1;
            }
            }
            else
            {
                return 0;
            }
        };
    m_Function = func;
}

程序在代码中的特定点崩溃。

最后,这是我如何通过模板专业化从API检索数据:

template<typename T>
inline T duk_get_arg(duk_context* ctx, int i);

template<>
inline std::string duk_get_arg<std::string>(duk_context* ctx, int i)
{
    char* ret_str;
    strcpy(ret_str, duk_require_string(ctx, i));
    std::string ret(ret_str);
    return ret;
}

template<>
inline int duk_get_arg<int>(duk_context* ctx, int i)
{
    int ret = duk_require_int(ctx, i);
    return ret;
}

template<>
inline unsigned int duk_get_arg<unsigned int>(duk_context* ctx, int i)
{
    unsigned int ret = duk_require_int(ctx, i);
    return ret;
}

template<>
inline float duk_get_arg<float>(duk_context* ctx, int i)
{
    float ret = (float)duk_require_number(ctx, i);
    return ret;
}

template<>
inline double duk_get_arg<double>(duk_context* ctx, int i)
{
    double ret = duk_require_number(ctx, i);
    return ret;
}

template<typename T_Return, typename ... T_Params, size_t ... T_Is>
inline T_Return duk_get_args_impl(duk_context* ctx, std::function<T_Return(T_Params ...)>& function_item, std::index_sequence<T_Is ...>)
{
    using tuple_type = std::tuple<T_Params ...>;
    T_Return ret;
    ret = function_item(duk_get_arg<std::tuple_element_t<T_Is, tuple_type>>(ctx, T_Is) ...);
    return ret;
}
template<typename T_Return, typename ... T_Params>
inline T_Return duk_get_args(duk_context* context, std::function<T_Return(T_Params ...)>& function_item)
{
    T_Return ret;
    ret = duk_get_args_impl<T_Return, T_Params ...>(context, function_item, std::index_sequence_for<T_Params ...>());
    return ret;
}

我有什么遗失/从根本上做错了吗?除了这样使用lambdas?我真的希望得到答案,因为我无法弄清楚导致错误的原因!在此先感谢:)

1 个答案:

答案 0 :(得分:0)

原来问题只是我的误解/我懒得查找strcpy()的文档。它没有为目标字符串分配内存,我必须这样做。使用

更改get_arg<std::string>方法有点诀窍
template<>
inline std::string duk_get_arg<std::string>(duk_context* ctx, int i)
{
    std::string ret(duk_require_string(ctx, i));
    return ret;
}

我现在得到以下输出:

>> var x = cnum("3");
"3"
>> print(x);
6
>>

再次感谢快速(明显)的答案!让我也吸取了教训:P