Указатель на экземпляр шаблона функции - PullRequest
0 голосов
/ 05 декабря 2011

Я хочу использовать шаблон функции thunk для передачи его в pthread_create и тому подобное.

Я бы ожидал, что компилятор создаст экземпляр функции с заданными параметрами, вся информация будет там, а затем использует typedef как функцию ptr для передачи этим функциям.

#include <string>
class ServerImpl{
    public:
        ServerImpl(std::string host, int port);
        void run();

};


template<typename T,void (T::*mem_fn)()>
void *thunk(void *obj) {
    (static_cast<T*>(obj)->*mem_fn)();
    return 0;
}

typedef void *(*Function) (void);
Function fun = (Function)&thunk<ServerImpl,&ServerImpl::run>;
fun();

ТОЛЬКО ИЗМЕНЕНО

Видите, с этим я получаю ошибку компоновщика, которая привела меня к предыдущей. Пропустите тот факт, что я должен передавать объект.

Server.o: In function `ServerImpl::ServerImpl(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int)':
Server.cpp:(.text+0x11f): undefined reference to `void* thunk<ServerImpl, &(ServerImpl::run())>(void*)'

Ответы [ 3 ]

3 голосов
/ 05 декабря 2011

thunk - это шаблон функции.Как вы можете использовать typedef на нем?Это не имеет смысла.Это не тип .Вы можете применять typedef только к типам.

Вы должны сделать это:

 ServerImpl *arg = new ServerImpl(); //why do I use new?
 pthread_create(&thread_id, NULL, &thunk<ServerImpl,&ServerImpl::run>, arg);

Ваши аргументы pthread_create неверны.Требуется 4 аргумента, а не 2.

Почему я использовал new?

Я создал экземпляр ServerImpl, используя new, потому что экземпляр должен существовать, даже если функция вкоторые вы создали тему вернули.Если я не создаю экземпляр, используя new, и вместо этого использую локальную переменную, тогда код вызывает неопределенное поведение, если функция вернулась, но поток продолжает работать.


Ответ на ваши изменения:

Function fun = (Function)&thunk<ServerImpl,&ServerImpl::run>;
fun();

Это неправильно.Потому что thunk принимает один аргумент.Поэтому вы должны сделать это вместо этого:

Function fun = (Function)&thunk<ServerImpl,&ServerImpl::run>;
fun(new ServerImpl); //pass an argument

Функция-член run вызывается для этого аргумента, который вы передали.

1 голос
/ 05 декабря 2011

Ошибка довольно проста.Это все равно что пытаться сделать

void f() { }
typedef f blah;

или

int a;
typedef a something;

Вам просто нужно будет сделать

pthread_create(&thread_id, &thunk<ServerImpl, &ServerImpl::run>);

Или, если хотите:

auto threadproc = &thunk<ServerImpl, &ServerImpl::run>;
pthread_create(&thread_id, threadproc);

И, что касается стилистики, пожалуйста, используйте пробелы после каждой запятой в списках аргументов:)

0 голосов
/ 05 декабря 2011

Я не знаю, пытается ли это сказать вам компилятор, но подпись thunk не использует какой-либо тип шаблона, как вы ожидаете, что компилятор угадает это?

Здесь pthread_create ожидает функцию, а не тип (typedef fun определяет тип, а не функцию)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...