Не знаю типы параметров шаблона при приведении void * к шаблонному типу - PullRequest
1 голос
/ 08 апреля 2011

Я использую библиотеку pthreads, и когда я создаю поток, я даю ему указатель на объект, который является шаблонным типом.

Я неопытен с шаблонами (только что прочитал о них сегодня), и мне нужно привести параметр 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()
}

Моя проблема в том, что я получаю все эти ошибки, которые я не знаю, как исправить. Я действительно понимаю ошибки, но не знаю решения. Вот ошибки:

ошибка: ожидаемое первичное выражение до (токен ошибка: пропущены аргументы шаблона перед * токеном ошибка: ожидаемое первичное выражение до) токен ошибка: ожидается `) 'перед' info '

Я просто не понимаю, как я мог узнать типы аргументов A, когда я приводил его один раз в потоке?

Я использую шаблоны C ++: полное руководство в качестве справочного / учебного ресурса и должен сказать, что я переполнен всей информацией, необходимой для полного понимания шаблонов. Мне было интересно, есть ли у кого-нибудь решение проблемы, или он мог бы указать мне другой источник, который мог бы дать ответы.

Как всегда, я очень ценю вашу помощь.

EDIT / UPDATE

Похоже, что добавление контекста к моей проблеме может помочь. В качестве альтернативы может быть кто-то может предложить другое решение, используя другой дизайн.

Я использую libcurl для выполнения HTTP-запросов, и в зависимости от полученного ответа я создам объект определенного типа (таким образом, шаблоны). Я создаю новый поток для каждого запроса, который я хочу сделать, чтобы все работало асинхронно.

Ответы [ 2 ]

5 голосов
/ 08 апреля 2011
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 какие-либо требования, чтобы они были одинаковыми, но если они отличаются, вам не повезло, потому что вы не можете дать шаблоны функций связи на языке Си.

2 голосов
/ 08 апреля 2011

Шаблоны классов не являются классами, они генерируют классы при заданных аргументах шаблона. Аналогично, вы не можете сделать печенье из печенья, пока не поставите тесто для печенья. Приведение к 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 должен работать равномерно на любом типе, это невозможно. Однако вы можете выделить общий интерфейс, независимый от типа, и обратиться к 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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...