Преобразование типа функции
От: Аноним  
Дата: 01.12.09 05:57
Оценка:
Как можно исхитриться сделав преобразование типа функции допустим:
int (class_a::)( int, void *) в int (*)(int, void *)

чтобы впоследствие сделать присвоение указателя функции к переменной последнего типа.
Re: Преобразование типа функции
От: Bell Россия  
Дата: 01.12.09 06:13
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Как можно исхитриться сделав преобразование типа функции допустим:

А>
А>int (class_a::)( int, void *) в int (*)(int, void *)
А>

А>чтобы впоследствие сделать присвоение указателя функции к переменной последнего типа.

Такое преобразование невозможно. Расскажи подробнее, зачем тебе это понадобилось. Возможно, тебе поможет связка boost.bind + boost.function.
Любите книгу — источник знаний (с) М.Горький
Re: Преобразование типа функции
От: LaptevVV Россия  
Дата: 01.12.09 06:25
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Как можно исхитриться сделав преобразование типа функции допустим:

А>
А>int (class_a::)( int, void *) в int (*)(int, void *)
А>

А>чтобы впоследствие сделать присвоение указателя функции к переменной последнего типа.
Указатель на метод в указатель на функцию преобразовать нельзя. Для этого обычно пишут классы — адаптеры, а потом — функции-обертки.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re: Преобразование типа функции
От: rg45 СССР  
Дата: 01.12.09 11:54
Оценка: 7 (2)
Здравствуйте, Аноним, Вы писали:

А>Как можно исхитриться сделав преобразование типа функции допустим:

А>
А>int (class_a::)( int, void *) в int (*)(int, void *)
А>

А>чтобы впоследствие сделать присвоение указателя функции к переменной последнего типа.

Тема, конечно, избитая донельзя, ну давай еще раз. Все нестатические функции-члены один имеют неявный параметр — указатель на объект для которого этот метод вызван. Когда мы пишем: my_object->some_foo(), на самом деле мы неявно вызываем функцию с одним параметром, а не с пустым списком параметров, как это может показаться при поверхностном взгляде. В данном случае этим параметром будет указатель my_object, который внутри функции some_foo() будет доступен как this.

Кроме списка параметров для функций, как свободных, так и функций-членов, существенен протокол вызова. Для свободных функций это может быть __cdecl, __stdcall или __fastcall. Для функций-членов допустимы все вышеперечисленные протоколы вызова плюс еще один — __thiscall, который используется по умолчанию. К чему я все это? К тому, что если мы собираемся заняться реинтерпретацией типов указателей на функции, то не учитывать протокол вызова нельзя.

Итак, пусть имеется некий класс A, в котором объявлена функция-член foo.
class A
{
public:
  int foo(int, void*);
};


Для MSVC при стандартных настройках объявление функции foo может быть интерпретировано как объявление обычной функции следующего вида:
int __thiscall foo(A*, int, void*);


Но тут одна проблема: мы не можем использовать __thiscall для свободных функций. Но зато мы можем изменить протокол вызова функции-члена:
class A
{
public:
  int__cdecl foo(int, void*);
};


Вот теперь можно заняться грязными хаками:
typedef int Handler(A*, int, void*); //Подразумевается, что по умолчанию протокол __cdecl
Handler* f = reinterpret_cast<Handler*>(&A::foo);
A a;
f(&a, 123, 0);


Существует более легальный способ преобразования функциональных объектов при с использованием boost::function, boost::bind, boost::mem_fn и иже с ними. По возможности, нужно стараться использовать именно эту технику во избежание разного рода неприятностей. Единственное ограничение этого подхода, это то, что в результате такого преобразования мы получаем функциональный объект, а не указатель на функцию. И если по специфике задачи нужен именно указатель а не функционал, то тут два пути: либо пускаться во все тяжкие, либо перепроектировать.
--
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.