2011-04-08 8 views
1

私はpthreadsライブラリを使用しています。スレッドを作成するときに、テンプレート型のオブジェクトへのポインタを与えています。void *をテンプレート型にキャストするときにテンプレートパラメータ型を知らない

私はテンプレートに慣れていないので(今日読んでいるだけです)、メソッド宣言からvoid *パラメータをキャストしてpthreadをテンプレート化した型にキャストする必要があります。このような短い何かで

:そうのように見える短い何かで

template <typename T> 
class A { 
    ... 
    ... 
    ... 
    void aMember() { ... } 
}; 

int main() { 
    A<int> a; 

    pthread_create(..., ..., &run, &a); 

    ... 
    ... 
    ... 
} 

void *run(void *arg) { 
    (A*)arg->aMember() 
} 

私の問題は、私は私が修正する方法がわからない、すべてのこれらのエラーを取得しています。私は実際にエラーを理解していますが、解決策を知らない。

エラー:期待の一次式の前(トークン エラー:*トークン エラーの前にテンプレート引数が不足して:前に予想される主な表現)トークン エラー:予想 `)情報」の前に『』

ここでエラーがあります

スレッドの中で一度キャストしているときに、どのように引数型を知ることができたのか分かりません。

私は、C++のテンプレート:参考書/参考資料として、テンプレートを完全に理解するために必要なすべての情報を提供しています。私は、誰かが問題の解決策を持っているのだろうか、それとも答えを提供するかもしれない別のリソースの方向に私を指し示すことができるのだろうかと思っていた。

いつものように私はあなたの助けを大いに感謝します。

EDIT/UPDATE

私の問題にコンテキストを追加することに役立つかもしれないと思われます。あるいは、誰かが別のデザインを使って別のソリューションを提供しているかもしれません。

私はlibcurlを使用してHTTPリクエストを作成していますが、受け取ったレスポンスに応じて、特定のタイプのオブジェクト(したがってテンプレート)を作成します。すべてのリクエストが非同期で実行されるように、新しいリクエストを作成します。

+0

なぜあなたはこのCをタグ付けしましたか? – GManNickG

+0

申し訳ありません。私は以前に私の問題にコンテキストを追加すべきですが、Imはpthreadライブラリを使用しています。 – Chris

答えて

5
template<typename T> 
void *run(void *arg) { 
    static_cast<A<T>*>(arg)->aMember(); 
} 

int main() { 
    A<int> a; 

    pthread_create(..., ..., &run<int>, &a); 

    ... 
    ... 
    ... 
} 

これは、元のコードスニペットのように、どのようなあなたのpthreadライブラリが使用すると同じになるように呼び出し規約にextern「C++」に頼るん。私は、POSIXが同じものであるという要件を持っているかどうかは分かりませんが、それらが異なる場合、関数テンプレートにC言語リンケージを与えることができないため、運が悪いです。

+1

litb。どのようなヒーロー。 –

+0

あなたがpthread_createで述べたリンケージの問題に遭遇していると思います。void * MyClass :: run >(void *)私が明らかに呼び出したときに実行します Chris

+0

@Chris '&run 'のように、スコープ内で 'run'の定義を持つ必要があります。 –

2

クラステンプレートはクラスではなく、はテンプレート引数が与えられたときにクラスを生成します。同様に、クッキードウを供給するまで、クッキーカッターからクッキーを作ることはできません。 Aへのキャスティングは無意味です。

you haven't said what you're trying to accomplish, just the step you're taking以降、正しい解決策が何であるかは言うまでもありません。runが1つのタイプでしか動作しない場合、テンプレート引数は常に同じであることがわかります。 runが異なるAインスタンス上で動作し、他の人を心配する必要はありません場合は、

void *run(void *arg) { 
    A<int>* a = static_cast<A<int>*>(arg); 
    a->aMember(); 
} 

run自体は、テンプレートを指定できます:あなたはこれを行うことが

template <typename T> 
void *run(void *arg) { 
    A<T>* a = static_cast<A<T>*>(arg); 
    a->aMember(); 
} 

pthread_create(..., ..., &run<int>, &a); 

runは、任意の上に均一に動作する必要がある場合これは不可能です。ただし、一般的なタイプに依存しないインタフェースを考慮し、非テンプレートベースを参照することができます。

class ABase { 
public: 
    // functionality present regardless of template argument 
    virtual void aMember() = 0; 

    // polymorphic bases should always have virtual destructors 
    virtual ~ABase() {} 
}; 

template <typename T> 
class A : public ABase { 
public: 
    void aMember() { /* use type information */ } 
}; 

void *run(void *arg) { 
    ABase* a = static_cast<ABase*>(arg); 
    a->aMember(); // dynamic dispatch 
} 
関連する問題