Я пытаюсь написать класс для анализа *.so, при компиляции возникла ошибка: нет соответствующей функции для вызова...
error: no type named 'type' in 'class std::result_of<std::result_of<std::function<int>(it)>'
, код следующий:
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));
}
592 template<typename T, typename... Args>
593 typename std::result_of<std::function<T>(Args...)>::type excecute_func(const string& funcName, Args&&... args) {
594 auto f = get_function<T>(funcName);
595 if (nullptr == f) {
596 string s = "can not find this function" + funcName;
597 throw std::exception(s.c_str());
598 }
599
600 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)>’
кто-нибудь может помочь, в чем проблема
ищу в интернете, пытаюсь исправить, но не получается
Кажется, первый параметр шаблона excecute_func предназначен для типа функции, например. void(int). Вы проходите мимо int. std::function<int> не имеет смысла. Возможно, вы имели в виду, что первый параметр должен быть возвращаемым типом, а Args — типом параметра — тогда скажите так, как в std::function<T(Args...)>. Хотя в данном случае result_of кажется ненужным — результатом функции, возвращающей T, будет, ну, T.





Вам следует переименовать тип T в Signature везде в предоставленном коде.
Тогда эта строка:
int ret = doip_lib_client.excecute_func<int, int>("init_doip_client", 1);
следует переписать так:
int ret = doip_lib_client.excecute_func<int(int)>("init_doip_client", 1);
и в целом все должно работать.
Хитрость в том, что аргумент шаблона T (плохо названный) является сигнатурой функции, которую вы оборачиваете. В данном случае это функция, которая принимает int и возвращает int, то есть int(int).
std::function<T>, где T = int не является допустимой специализацией std::function, и даже если бы это было так, std::function<T>(Args...) — это тип функции, который принимает Args... и возвращает std::function<T>.
Похоже, T — это ваш тип результата, поэтому typename std::result_of<???>::type вам вообще не нужен.
Также обратите внимание, что std::ref здесь также недопустимо, перегрузка, принимающая значение r, равна = deleted. Если вам нужна функция, возвращающая ссылку, передайте тип ссылки как T.
template<typename T, typename... Args>
T excecute_func(const string& funcName, Args&&... args) {
auto f = get_function<T(Args...)>(funcName);
if (nullptr == f) {
throw std::runtime_error("can not find this function" + funcName);
}
return f(std::forward<Args>(args)...);
}
Я решил это: int ret = doip_lib_client.excecute_func<int(int)>("init_doip_client", 1);