You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

编写*.so解析类遇编译错误:std::result_of无type类型

SO文件解析类编译错误解析

问题概述

编写SO文件解析C++类时,遇到两个核心编译错误:

  1. no type named 'type' in 'class std::result_of<std::function<int>(int)>'
  2. 函数调用不匹配

相关代码

template<typename T>
std::function<T> get_function(const string& funcName) {
    auto it = m_map.find(funcName);
    if (it == m_map.end()) {
        auto addr = dlsym(m_libHandler, funcName.c_str());
        if (nullptr == addr) {
            return nullptr;
        }

        m_map.emplace(std::make_pair(funcName, addr));
        it = m_map.find(funcName);
    }

    return std::function<T>((T*)(it->second));
}

template<typename T, typename... Args>
typename std::result_of<std::function<T>(Args...)>::type excecute_func(const string& funcName, Args&&... args) {
    auto f = get_function<T>(funcName);
    if (nullptr == f) {
        string s = "can not find this function" + funcName;
        throw std::exception(s.c_str());
    }

    return std::ref(f(std::forward<Args>(args)...));
}

int main() {
    int ret = doip_lib_client.excecute_func<int, int>("init_doip_client", 1);
}

编译错误信息

cplusplus_prac.cpp: In function ‘int main()’:
cplusplus_prac.cpp:615:76: error: no matching function for call to ‘SoParser::excecute_func<int, int>(const char [17], int)’
  615 |         ret = doip_lib_client.excecute_func<int, int>("init_doip_client", 1);
      |                                                                            ^
cplusplus_prac.cpp:593:62: note: candidate: ‘template<class T, class ... Args> typename std::result_of<std::function<T>(Args ...)>::type SoParser::excecute_func(const string&, Args&& ...)’
  593 |     typename std::result_of<std::function<T>(Args...)>::type excecute_func(const string& funcName, Args&&... args) {
      |                                                              ^~~~~~~~~~~~~
cplusplus_prac.cpp:593:62: note:   template argument deduction/substitution failed:
cplusplus_prac.cpp: In substitution of ‘template<class T, class ... Args> typename std::result_of<std::function<T>(Args ...)>::type SoParser::excecute_func(const string&, Args&& ...) [with T = int; Args = {int}]’:
cplusplus_prac.cpp:615:76:   required from here
cplusplus_prac.cpp:593:62: error: no type named ‘type’ in ‘class std::result_of<std::function<int>(int)>’

错误原因与修复方案

1. std::result_of使用逻辑错误

std::result_of<std::function<T>(Args...)>的写法完全错误:

  • 当你传入T=int时,std::function<int>代表无参且返回int的函数包装器,但你却试图传入int类型参数,导致类型不匹配,std::result_of无法推导有效类型。
  • 正确的设计应该让模板参数T代表完整的函数签名(比如int(int)),而非单纯的返回值类型。

2. get_function模板参数设计偏差

原get_function<T>中T被当作返回值类型,但实际上需要接收完整函数签名,才能正确构建std::function对象。

3. 返回值的std::ref冗余错误

f(std::forward<Args>(args)...)已经返回函数的实际结果(这里是int),用std::ref包裹会返回std::reference_wrapper<int>,与声明的返回类型冲突,直接返回调用结果即可。

4. 函数调用参数传递错误

原调用excecute_func<int, int>中,第一个模板参数是返回值类型,不符合函数签名的设计逻辑,需要改为传递完整函数签名。


修正后的代码示例

修正get_function

// T为完整函数签名,比如int(int)
template<typename T>
std::function<T> get_function(const std::string& funcName) {
    auto it = m_map.find(funcName);
    if (it == m_map.end()) {
        auto addr = dlsym(m_libHandler, funcName.c_str());
        if (nullptr == addr) {
            return nullptr;
        }

        m_map.emplace(funcName, addr);
        it = m_map.find(funcName);
    }

    // 用reinterpret_cast更规范
    return std::function<T>(reinterpret_cast<T*>(it->second));
}

修正excecute_func

// 改用decltype(auto)简化返回值推导(C++14及以上)
template<typename FuncSig, typename... Args>
decltype(auto) excecute_func(const std::string& funcName, Args&&... args) {
    auto f = get_function<FuncSig>(funcName);
    if (!f) {
        throw std::runtime_error("can not find function: " + funcName);
    }

    return f(std::forward<Args>(args)...);
}

修正调用代码

int main() {
    // 传入完整函数签名int(int)作为模板参数
    int ret = doip_lib_client.excecute_func<int(int)>("init_doip_client", 1);
}

内容的提问来源于stack exchange,提问作者user23267295

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 04:06:18