2013-07-05 102 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);