【问题标题】:Template specialization crash [closed]模板专业化崩溃[关闭]
【发布时间】:2016-02-24 14:22:16
【问题描述】:

各位 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;
}

我有什么遗漏/做错了吗?除了以这种方式使用 lambda?我真的希望得到答案,因为我无法弄清楚是什么导致了错误!在此先感谢:)

【问题讨论】:

  • char* ret_str; strcpy(ret_str, duk_require_string(ctx, i));我察觉到了问题
  • 事情,是我的回答不能是最小和完整的。我认为这是尽可能少的,正如我所说,绑定工作正常,我只是检查了它执行时包含在 lambda 中的值是否也很好。他们是。所以问题完全在于我对duk_get_args 的实现。 @PiotrSkotnicki 你是什么意思,我在这里做错了吗?我正在将 const char* 复制到 char*
  • @calcyss 您的问题绝对可以是最小的和完整的。只要继续删除东西,直到你可以产生自给自足的东西,仍然会重现错误。很有可能,只要这样做,您就会自己发现问题。照原样,这只是一段代码,其中许多函数未定义,Piotr 碰巧注意到了其中的一个问题。这不是真正获得帮助的好方法。
  • @calcyss 这个问题可以最小化。对于每一行,如果删除它,错误是否仍然发生? std::cout &lt;&lt; "wrong number of arguments! retreating!" &lt;&lt; std::endl; 我敢打赌,删除该行仍然会使代码崩溃,我花了 5 秒钟才找到。要么您无法删除代码行,要么您没有尝试?完成该过程后,您就可以处理逻辑了——您可以跳过整个逻辑层来重现问题吗?找出崩溃发生的位置,只重现那行代码并重现崩溃?是的,这需要工作。

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


【解决方案1】:

原来问题只是我的误解/我懒得去查看strcpy() 的文档。它不会为目标字符串分配内存,我必须这样做。稍微改变 get_arg&lt;std::string&gt; 方法就可以了,用

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

【讨论】:

    猜你喜欢
    • 2020-07-18
    • 2016-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-28
    • 2015-08-01
    • 2011-09-23
    相关资源
    最近更新 更多