编写*.so解析类遇编译错误:std::result_of无type类型
SO文件解析类编译错误解析
问题概述
编写SO文件解析C++类时,遇到两个核心编译错误:
no type named 'type' in 'class std::result_of<std::function<int>(int)>'- 函数调用不匹配
相关代码
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
相关产品推荐
相关产品推荐

