1

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)います。

4

2 に答える 2

1

コールバック関数はいつでもテンプレート化できます。

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

    // ... rest of code ...
}
于 2013-07-05T23:00:07.580 に答える
0

簡単な答えは、できないということです。「何にキャストしているのか」を知る必要があります。

もちろん、これを解決するにはさまざまな方法があります。私が最初に考えたのは、実際のストレージを実装するインターフェイス クラスを使用することです。

したがって、イテレーターを download_to_container のパラメーターとして使用する代わりにOutIt、関連する操作を行うクラスを使用します。

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);
于 2013-07-05T23:08:25.003 に答える