将 void* 转换为模板类型时不知道模板参数类型

发布于 2024-10-31 03:02:07 字数 921 浏览 0 评论 0原文

我正在使用 pthreads 库,当我创建线程时,我给它一个指向模板类型对象的指针。

我对模板缺乏经验(今天刚刚阅读了它们),需要将 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()
}

我的问题是我遇到了所有这些错误,我不知道如何纠正。事实上我确实理解这些错误,但不知道解决方案。以下是错误:

错误:预期的主表达式之前(令牌 错误:* 标记之前缺少模板参数 错误:在 ) 标记之前需要主表达式 错误:在“info”之前预期有“)”

我只是不明白当我在线程中一次转换为 A 时,如何知道 A 的参数类型?

我正在使用《C++ 模板:完整指南》一书作为参考/学习资源,并且必须说我对完全理解模板所需的所有信息感到不知所措。我想知道是否有人能解决该问题,或者可以为我指出另一个可能提供答案的资源的方向。

一如既往,我非常感谢您的帮助。

编辑/更新

似乎为我的问题添加上下文可能会有所帮助。或者,也许有人可以使用不同的设计提供不同的解决方案。

我使用 libcurl 发出 HTTP 请求,并根据收到的响应创建特定类型的对象(即模板)。我为每个想要发出的请求创建一个新线程,以便一切都异步运行。

I am using the pthreads library and when I create a thread I am giving it the pointer to an object that is a templated type.

I'm inexperienced with templates (just read about them today) and need to cast the void* parameter from the method declaration the pthread runs to the templated type so I can access its members. In short something that looks like so:

In short something like this:

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

int main() {
    A<int> a;

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

    ...
    ...
    ...
}

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

My problem is I get all these errors that I don't know how to rectify. I do in fact understand the errors but don't know the solution. Here are the errors:

error: expected primary-expression before ( token
error: missing template arguments before * token
error: expected primary-expression before ) token
error: expected `)' before 'info'

I just don't see how I could ever know the argument types of A when I am casting to it once in the thread?

I'm using the C++ Templates: The Complete Guide book as a reference/learning resource and must say I am over whelmed with all the info needed to fully understand templates. I was wondering if anyone had a solution to the problem, or could point me in the direction of another resource that might provide answers.

As always I appreciate your help greatly.

EDIT/UPDATE

It seems that adding context to my problem might help. Alternatively maybe someone can provide a different solution using a different design.

I am using libcurl to make HTTP Requests and depending on the Response I receive I will create an object of a specific type (thus the templates). I create a new thread for each Request I would like to make so that everything runs Asynchronously.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

沫离伤花 2024-11-07 03:02:07
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 语言链接。

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

int main() {
    A<int> a;

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

    ...
    ...
    ...
}

This does, like your original code snippet, rely on extern "C++" calling convention to be the same as what your pthread library uses. I'm not sure whether POSIX has any requirements that those be the same, but if they differ you are out of luck, because you cannot give function templates C language linkage.

匿名。 2024-11-07 03:02:07

类模板不是类,它们在给定模板参数时生成类。同样,在提供饼干面团之前,您无法用饼干切割机制作饼干。转换为 A 是没有意义的。

很难说正确的解决方案是什么,因为你还没有说出你的意思尝试完成您正在采取的步骤。如果 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
}

Class templates are not classes, they generate classes when given template arguments. Likewise, you cannot make a cookie from a cookie cutter until you supply cookie dough. Casting to A is meaningless.

It's hard to say what the right solution is since you haven't said what you're trying to accomplish, just the step you're taking. If run should only ever work on one type, you know the template argument will always be the same; you could do this:

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

If run can operate on different A instantiations, and need not worry about others, run itself can be a template:

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

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

If run needs to operate uniformly on any type, this is not possible. You can, however, factor out the common type-independent interface, and refer to a non-template base:

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
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文