2013-07-05 3 views
0

Я хочу написать функцию, которая будет использовать libcurl для файла, а затем сохранить в контейнер. Я бы хотел использовать итераторы для абстрагирования типа контейнера. Функция будет выглядеть следующим образом:Кастинг неизвестного типа

template <typename OutIt> 
bool download_to_container(const std::string& link, OutIt out) 
{ 
    //set the write callback 
    //perform the action 
    //return whatever 
} 

обратного вызова записи является функцией подписи size_t(char*, size_t, size_t, void *userdata) где userdata указатель я могу установить, что Libcurl будет проходить в обратный вызов записи для меня.

userdata станет указателем на выходной итератор, который пользователь перешёл в download_to_container. Теперь, как только будет вызван обратный вызов, мне придется отдать это void* в OutIt*. Как я могу это сделать, если я не знаю тип итератора? Это первый раз, когда я сталкиваюсь с этой проблемой, поэтому, пожалуйста, успокойся. :-)

Я использую Microsoft Visual C++ Compiler Nov 2012 CTP (v120_CTP_Nov2012).

ответ

1

Вы всегда можете запланировать функцию обратного вызова.

template<typename Iterator> 
size_t callbackFunc(char*, size_t, size_t, void *userdata) 
{ 
    Iterator it = *static_cast<Iterator*>(userdata); 

    // ... rest of code ... 
} 
+0

Только то, что мне нужно. Я серьезно не знаю, почему я об этом не думал. Я застрял в этой странной идее, что обратный вызов не может быть шаблоном функции, потому что я имел дело с C API. Тут, странно. В любом случае, спасибо! :) – Tuntuni

0

Простой ответ заключается в том, что вы не можете. Вам нужно знать, к чему вы клоните.

Конечно, есть несколько способов решить эту проблему. Моя первая мысль - использовать класс интерфейса, который реализует фактическое хранилище.

Таким образом, вместо того, чтобы использовать OutIt итератор в качестве параметра для вашего download_to_container, вы используете класс, который делает соответствующую операцию:

class VectorStorer 
{ 
    public: 
    static size_t store(char *ptr, size_t size, size_t nmemb, void *userdata) 
    { 
     VectorStorer *self = static_cast<VectorStorer *>(userdata); 
     return self->do_Store(ptr, size, nmemb); 
    } 

    private: 
    vector<char> v; 
    size_t do_store(char *ptr, size_t size, size_t nmemb) 
    { 
     ... store stuff in vector v. 
     return size; 
    } 
}; 

template <typename StoreT> 
bool download_to_container(const std::string& link, StoreT& storer) 
{ 
    curl_opt(ch, CURLOPT_WRITE_DATA, &storer); 
    curl_opt(ch, CURLOPT_WRITEFUNCTION, &storer.store); 
    //perform the action 
    //return whatever 
} 

VectorStorer vs; 
download_to_container("www.example.com", vs); 
Смежные вопросы