Я пытаюсь написать класс для анализа *.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, равна = delete
d. Если вам нужна функция, возвращающая ссылку, передайте тип ссылки как 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);