包含可解释函数的编译器错误

时间:2018-04-21 14:00:45

标签: c++

我有一个遗留的C代码库,我将以零散的方式迁移到C ++。它包括一个解释器,因此需要包装静态函数和参数以供解释器使用。因此,导出到解释器的典型功能可能具有以下签名:

static void do_strstr(struct value * p)

并像这样接触翻译:

using vptr = void (*) ();
template <typename Func>
constexpr vptr to_vptr(Func && func)
{ return reinterpret_cast<vptr>(func); }


struct function string_funs[] = {
     ...
        { C_FN3,        X_A3,   "SSI",  to_vptr(do_strstr),     "find" },
    ...
    };

这已被证明有效。到目前为止,该方法的缺点是被调用的函数必须将内存分配到临时堆栈上。例如,改进的地方是被调用的函数只返回一个字符串。然后包装此函数,其中包装器在幕后完成记忆魔术。这允许以更香草的方式创建函数。

这是一个使用我的改进方法连接两个字符串的实现:

static std::string do_concata(struct value* p)
{
        std::string s1 = (p)->gString();
        std::string s2 = (p+1)->gString();
        return s1+s2;
}

我创建了一个辅助函数:

static void do_concata_1(struct value* p)
{
        wrapfunc(do_concata)(p);
}

其中有点通用的包装器定义为:

std::function<void(struct value*)>
wrapfunc(std::function<std::string(struct value*)> func)
{
        auto fn = [=](struct value* p) { 
                std::string s = func(p);
                char* ret = alloc_tmp_mem(s.size()+1);          
                strcpy(ret,  s.c_str());
                p->sString(ret);
                return; 
        };
        return fn;
}

如下所示接触解释器:

struct function string_funs[] = {
...
{ C_FN2,        X_A2,   "SS",    to_vptr(do_concata_1),    "concata" },
...

};

我对此解决方案不满意,因为它需要为我定义的每个函数提供辅助函数。如果我可以消除do_concata_1并编写另一个包裹wrapfunc的函数,那会更好。

这就是问题所在。如果我写:

vptr to_vptr_1(std::function<void(struct value*)> func)
{
        return to_vptr(wrapfunc(func));
}

然后编译器抱怨:

stringo.cc: In function ‘void (* to_vptr_1(std::function<void(value*)>))()’:
stringo.cc:373:30: error: could not convert ‘func’ from ‘std::function<void(value*)>’ to ‘std::function<std::__cxx11::basic_string<char>(value*)>’
  return to_vptr(wrapfunc(func));

这在我看来很奇怪,因为std::__cxx11::basic_string<char>来自哪里?肯定应该是void

我不知道该修复应该是什么。关于我是否应该传递函数副本,函数引用或神秘的&& r-vale引用,我也有点困惑。

1 个答案:

答案 0 :(得分:0)

func中,void被建立为返回func的函数。但是wrapfunc()传递给std::string,它需要一个返回func的函数。编译器无法将std::function<void(struct value*)>std::function<std::string(struct value*)>转换为reinterpret_cast,因此会发出错误消息。

std::function到原始函数指针的

{{1}}无法正常工作。 This question对此主题进行了一些很好的讨论,this one有一个解决方案可能会针对这种情况进行重新设计。