2011-04-08 65 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 
}