2011-04-08 92 views
1

我正在使用pthreads庫,並且在創建線程時我將它指向模板類型的對象。在將void *轉換爲模板類型時,不知道模板參數類型

我對模板經驗不足(今天剛剛閱讀了他們),並且需要將pthread運行的方法聲明中的void *參數強制轉換爲模板類型,以便可以訪問其成員。總之東西,看起來像這樣:

總之是這樣的:

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

int main() { 
    A<int> a; 

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

    ... 
    ... 
    ... 
} 

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

我的問題是我得到所有這些錯誤,我不知道該如何糾正。我確實瞭解錯誤但不知道解決方案。下面是錯誤的:

錯誤:預期主表達式前(令牌 錯誤:前*令牌 錯誤缺少模板參數:預期主表達式前)令牌 錯誤:「之前‘的信息預期`)’

我只是沒有看到我怎麼能知道A的參數類型,當我在線程中一次投射它時?

我正在使用C++模板:作爲參考/學習資源的完整指南手冊,並且必須說我完全瞭解了需要完全理解模板的所有信息。我想知道是否有人解決了這個問題,或者可以指出另一個可能提供答案的資源。

一如既往,我非常感謝您的幫助。

編輯/ UPDATE

看來,加入背景下我的問題可能會有所幫助。或者,也許有人可以使用不同的設計提供不同的解決方案。

我使用libcurl發出HTTP請求,並根據我收到的響應我將創建一個特定類型的對象(因此模板)。我爲每個要創建的請求創建一個新線程,以便一切都異步運行。

+0

你爲什麼標記該C? – GManNickG 2011-04-08 00:35:47

+0

對不起。我應該早些時候給我的問題添加上下文,但是我使用pthreads庫。 – Chris 2011-04-08 16:32:25

回答

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

int main() { 
    A<int> a; 

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

    ... 
    ... 
    ... 
} 

這樣做,就像你原來的代碼片段一樣,依賴於extern「C++」調用約定與你的pthread庫使用的相同。我不確定POSIX是否有任何相同的要求,但如果它們不一樣,那麼你運氣不好,因爲你不能給函數模板C語言鏈接。

+1

litb。多麼英雄。 – 2011-04-08 00:40:45

+0

我想我遇到了你提到的連接問題,因爲它在pthread_create中它說undefined引用void * MyClass :: run >(void *)當我明顯調用run時使用 Chris 2011-04-08 16:28:21

+0

@Chris當你說'&運行',你需要在範圍內定義'run'。 – 2011-04-08 16:37:58

2

類模板不是類,它們在給定模板參數時生成類。同樣,在供應餅乾麪糰之前,您無法使用曲奇餅刀製作餅乾。鑄造到A是沒有意義的。

you haven't said what you're trying to accomplish, just the step you're taking開始,很難說正確的解決方案。如果run應該只能在一種類型上工作,則您知道模板參數將始終相同;你可以這樣做:

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

如果run可以在不同A實例操作,而不用擔心別人,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 
}