2014-09-19 3 views
2

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

int funct1(int x){ 
    return x*x; 
} 
class foo{ 
public: 
    int funct2(int x){ 
     return x*x; 
    } 
}; 
int conv(int (*f)(int)){ 
    return f(1); 
} 
int main(){ 
    conv(funct1); 
    foo bar; 
    conv(funct2); 
} 

Я понимаю, что funct2 является внутренний метод класса Foo, но при попытке изменить усл (funct2) к чему-то вроде конв (bar.funct2) дает ошибку, как:

argument of type ‘int (foo::)(int)’ does not match ‘int (*)(int)’ 

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

+2

Причина, по которой все остальные части кода сложны, заключается в следующем: простого решения нет. Вы принципиально не можете этого сделать. Указатель функции-члена не может быть преобразован в указатель свободной функции. Конец истории. Сожалею. –

+0

Нестатические функции-члены принимают 'this' как скрытый аргумент. Однако он должен работать со статическими функциями-членами. –

+0

, если вы в порядке с использованием C++ 11, меняя типы, используя 'std :: function' и, возможно, lambdas, тогда вы можете это сделать. Но с вашими ограничениями типа это невозможно сделать (как заявил @Konrad) – MariusSiuram

ответ

0

Я нашел хороший способ решить эту проблему:

class MyClass; 
static MyClass* ptr; 
class MyClass{ 
void Func(){something;} 
static void Func2(){ptr->Func();} 
void RunFunc(){ 
ptr=this; 
RunningExternalFunction(Func2); 
} 
}; 

вуаля!

1

объявить funct2 как статические

int funct1(int x){ 
return x*x; 
} 
class foo{ 
public: 
static int funct2(int x){ 
return x*x; 
} 
}; 
int conv(int (*f)(int)){ 
return f(1); 
} 
int main(){ 
conv(funct1); 
foo bar; 
conv(foo::funct2); 
} 
0

Если ваш компилятор поддерживает C++ 11 вы можете сделать следующее:

#include<functional> 

int funct1(int x){ 
    return x*x; 
} 
class foo{ 
public: 
    int funct2(int x){ 
     return x*x; 
    } 
}; 

int conv(int (*f)(int)){ 
    return f(1); 
} 

int main(){ 
    conv(funct1); 
    foo bar; 
    auto boundFunct2 = std::function<int(int)>(std::bind(&foo::funct2,bar,std::placeholders::_1)); 
    conv(boundFunct2.target<int(int)>()); 
} 

В принципе, вы связываете funct2 к экземпляру класса, а именно bar, а затем создать объект функции из этого. Для того, чтобы сделать подпись ожидаемой с помощью conv(), вы вызываете целевой элемент объекта функции.

Приятно, что вам не нужно изменять какие-либо функции или классы, которые, как я предполагаю, не могут, поскольку они, вероятно, являются объектами библиотеки openGL.

+0

temp.cpp: функция 'int main()': temp.cpp: 21: 10: error: 'boundFunct2' не называет тип temp.cpp: 22: 10: error: 'boundFunct2' не был объявлен в этой области temp.cpp : 22: 29: ошибка: ожидаемое первичное выражение перед 'int' Извините, ваш код не работает. –

+0

Он компилируется на msvc2010. Ваш компилятор должен поддерживать C++ 11 для его компиляции. –

+0

Этот код segfaults для меня (g ++ 4.8.3). Результат 'target()' является нулевым указателем –

Смежные вопросы