«Нет подходящей функции для вызова» с вариадическими шаблонами - PullRequest
1 голос
/ 18 января 2012

У меня есть класс, который предназначен для динамической загрузки .dll или .so или его эквивалента. Оттуда он вернет указатели на любую функцию, которую вы пытаетесь найти. К сожалению, я столкнулся с двумя проблемами в моей реализации.

  1. Если я использую функцию 'dumb', возвращающую void * в качестве указателей на функции, я получаю warning: ISO C++ forbids casting between pointer-to-function and pointer-to-object, когда пытаюсь манипулировать ими в форме, которую я могу использовать.
  2. Если я попытаюсь использовать «умную» функцию с шаблонами переменных и безопасностью типов, я не смогу ее скомпилировать. error: no matching function for call to ‘Library::findFunction(std::string&)’ это единственное, что меня здесь ждет. Как видно из кода ниже, это должно соответствовать сигнатуре функции. Как только он скомпилируется, проблема 1 будет присутствовать и здесь.

Для справки, я компилирую в Ubuntu 10.10 x86_64 с g++ (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5. Я также попытался скомпилировать с g++-4.5 (Ubuntu/Linaro 4.5.1-7ubuntu2) 4.5.1, но это ничего не меняет.

#include <string>
#include <stdio.h>

class Library
{
public:
    Library(const std::string& path) {}
    ~Library() {}

    void* findFunction(const std::string& funcName) const
    {
        // dlsym will return a void* as pointer-to-function here.
        return 0;
    }

    template<typename RetType, typename... T>
    RetType (*findFunction(const std::string& funcName))(T... Ts) const
    {
        return (RetType (*)(...))findFunction(funcName);
    }

};

int main()
{
    Library test("/usr/lib/libsqlite3.so");

    std::string name = "sqlite3_libversion";
    const char* (*whatwhat)() = test.findFunction<const char*, void>(name);
    // this SHOULD work. it's the right type now! >=[

    //const char* ver3 = whatwhat();
    //printf("blah says \"%s\"\n", ver3);
}

1 Ответ

1 голос
/ 18 января 2012

Я думаю, вам нужно изменить сигнатуру возвращаемой функции на T... вместо ..., в противном случае она ожидает переменную arglist, даже если она должна быть просто пустой.

template<typename RetType, typename... T>
RetType (*findFunction(const std::string& funcName))(T... Ts) const
{
    return (RetType (*)(T...))findFunction(funcName);
}

Затем вызовите его без void в списке типов, и оно должно работать:

const char* (*whatwhat)() = test.findFunction<const char*>(name);

С этими изменениями он компилируется для меня на gcc-4.5.1: http://ideone.com/UFbut

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...