Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Приведение указателя на функцию-член к void* 
:(
    Опции темы
AtroX
  Дата 22.8.2005, 23:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 18.8.2005

Репутация: нет
Всего: нет



Задача написать специализацию (или специализации) функции
Код

template <typename T, typename U> U MakeAnyPtr(T);


Которая позволяет делать так:
Код

struct Some {
   void f();
};

void main()
{
   Some *ps    = new Some;
   void   *p_fn = MakeAnyPtr<void*>(Some::f);

   (ps->*MakeAnyPtr<void (Some::*)()>(p_fn))();
}


PM MAIL   Вверх
Дрон
Дата 22.8.2005, 23:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java-ненавистник :)
****


Профиль
Группа: Участник Клуба
Сообщений: 3179
Регистрация: 29.12.2002
Где: Санкт-Петербург

Репутация: 10
Всего: 92



AtroX
Хех... Уже писал, но напишу ещё разок. Уж очень меня это прёт smile

Код

template <typename SRC_T, typename DEST_T>
DEST_T MakeAnyPtr(SRC_T inptr)
{
    union 
    {
        SRC_T  _inptr;
        DEST_T _outptr;
    };
    _inptr = inptr;
    return _outptr;
}


http://forum.vingrad.ru/index.php?showtopi...ndpost&p=413508


--------------------
Да. Именно так.
PM   Вверх
srd
Дата 23.8.2005, 04:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Нереварин
**


Профиль
Группа: Участник Клуба
Сообщений: 951
Регистрация: 30.8.2003
Где: Владивосток

Репутация: 27
Всего: 49



НЕЛЬЗЯ ТАК ДЕЛАТЬ! Кто сказал, что указатель на функцию-член имеет одинаковый размер с обычным указателем? В простейшем случае так и есть, но в случае множественного наследования/виртуальных функций - нет.

Вот пример:
Код

class R
{
};

class R1 : public virtual R
{
};

class R2 : public virtual R
{
};

class A : public R1, public R2
{
public:
    void func( void )
    {
    }
};

template <typename DEST_T, typename SRC_T>    
DEST_T MakeAnyPtr(SRC_T inptr)    
{    
    union    
    {    
        SRC_T  _inptr;    
        DEST_T _outptr;    
    };    
    _inptr = inptr;    
    return _outptr;    
}

int main( void )
{
    void* p = MakeAnyPtr<void*>( A::func );

    // Указатель на функцию член безвозратно потерян, т.к. он не влазит в 4-байта.
    void (A::*pf)(void) = MakeAnyPtr<void (A::*)(void)>( p );

    A a;
    (a.*pf)(); // Программа тут свалится.

    return 0;
}




--------------------
Не смей читать мою подпись!!!
PM MAIL Jabber   Вверх
AtroX
Дата 23.8.2005, 11:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 18.8.2005

Репутация: нет
Всего: нет



Цитата(srd @ 23.8.2005, 04:54)
// Указатель на функцию член безвозратно потерян, т.к. он не влазит в 4-байта.

sizeof(void (A::*)(void)) == 12, офигеть!

Цитата
Хех... Уже писал, но напишу ещё разок. Уж очень меня это прёт

Ага, обломчик, нельзя так..
Задачка то не тривиальна smile

Это сообщение отредактировал(а) AtroX - 23.8.2005, 11:22
PM MAIL   Вверх
Fantasist
Дата 23.8.2005, 12:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй
***


Профиль
Группа: Участник Клуба
Сообщений: 1517
Регистрация: 24.3.2002

Репутация: 4
Всего: 41



AtroX

Ты уверен, что хочешь иметь именно функцию, которая бы приводила бы указатель на метод к указателю void*? Потому как средствами языка это невозможно (хотя можно с помощью ассемблера). Возможно, вернуть указатель на объект, который будет представлять этот метод, но тогда появляется проблема удаления этого объекта.

В STL есть функция mem_fun() которая возвращает объект mem_fun_t, который представляет указетель на метода класса.

Код


#include <functional>

struct Some {
   void f();
};

int main()
{
   Some* p = new Some();
   
   std::mem_fun_t<void,Some> pM(&Some::f);

   pM(p); //p->f(); 
}





--------------------
Волны гасят ветер...
PM MAIL   Вверх
Дрон
Дата 23.8.2005, 12:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java-ненавистник :)
****


Профиль
Группа: Участник Клуба
Сообщений: 3179
Регистрация: 29.12.2002
Где: Санкт-Петербург

Репутация: 10
Всего: 92



Цитата(srd @ 23.8.2005, 05:54)
но в случае множественного наследования/виртуальных функций - нет.

Ибо нефиг. Я, кстати, об этом догадывался
Цитата
Кроме того, с виртуальными функциями такой фокус может быть опасен (хотя я не уверен -- сам не проверял).


А вообще Fantasist правильную вещь говорит smile


--------------------
Да. Именно так.
PM   Вверх
AtroX
Дата 23.8.2005, 17:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 18.8.2005

Репутация: нет
Всего: нет



Цитата(Fantasist @ 23.8.2005, 12:13)
Ты уверен, что хочешь иметь именно функцию, которая бы приводила бы указатель на метод к указателю void*?

Не надо, без хака все равно не получится.

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

Цитата(Fantasist @ 23.8.2005, 12:13)
В STL есть функция mem_fun() которая возвращает объект mem_fun_t, который представляет указетель на метода класса.

Там всего 0 или 1 переменная может быть - не катит, проще использовать из boost'а или самому написать.
PM MAIL   Вверх
Fantasist
Дата 23.8.2005, 18:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй
***


Профиль
Группа: Участник Клуба
Сообщений: 1517
Регистрация: 24.3.2002

Репутация: 4
Всего: 41



Цитата(AtroX @ 23.8.2005, 14:47)
Не надо, без хака все равно не получится.

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


Не понял ни первого ни второго предложения. smile Чего "не надо", и чего не получится?

Зачем надо динамически выделять память под функтор?


Цитата(AtroX @ 23.8.2005, 14:47)
Там всего 0 или 1 переменная может быть - не катит, проще использовать из boost'а


Можно, конечно, просто в соседней ветке ты написал тоже только для одного/двух параметров фактически переписав STL. А самому писать не стоит - boost вскоре тоже собираются в стандарт включать.


--------------------
Волны гасят ветер...
PM MAIL   Вверх
AtroX
Дата 23.8.2005, 20:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 18.8.2005

Репутация: нет
Всего: нет



Цитата(Fantasist @ 23.8.2005, 18:40)
Чего "не надо"

Не надо к void* приводить, плохая это идея =))

Цитата(Fantasist @ 23.8.2005, 18:40)
А самому писать не стоит

Иногда стоит, когда не хочешь подключать всю библиотеку(ну или часть).
Цитата(Fantasist @ 23.8.2005, 18:40)
Зачем надо динамически выделять память под функтор?

Чтобы хранить в этом функторе нормальный указатель на мембер, раз я не знаю его размера. Как и сделано в соседней ветке.


Цитата(Fantasist @ 23.8.2005, 18:40)
Можно, конечно, просто в соседней ветке ты написал тоже только для одного/двух параметров фактически переписав STL.

У меня у функторов общий базовый класс, что важно и чего нет в STL.
Для одного и двух пар-ров я сделал только для примера, а вообще реально нужно около 4х.
PM MAIL   Вверх
Chaos A.D.
Дата 24.8.2005, 09:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 172
Регистрация: 16.1.2005
Где: 09 RUS

Репутация: 6
Всего: 7



Цитата(AtroX @ 23.8.2005, 20:00)
Чтобы хранить в этом функторе нормальный указатель на мембер, раз я не знаю его размера.

Не знаю, подойдет ли тебе это, но функтор можно, и, имхо, нужно передавать по значению. Так же, если нужна общность функторов для разного типа и количества аргументов, и без наследования, советую присмотреться к Loki::Functor
--------------------
Надо смеяться над тем, что тебя мучит, иначе не сохранишь равновесия, иначе мир сведет тебя с ума...Ken Kesey - One Flew Over The Cocoo's Nest
PM MAIL   Вверх
AtroX
Дата 24.8.2005, 16:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 18.8.2005

Репутация: нет
Всего: нет



Цитата(Chaos @ 24.8.2005, 09:15)
Не знаю, подойдет ли тебе это, но функтор можно, и, имхо, нужно передавать по значению.


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

Это сообщение отредактировал(а) AtroX - 24.8.2005, 16:32
PM MAIL   Вверх
Nastya
Дата 24.8.2005, 17:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 27.3.2002
Где: Мариуполь

Репутация: 5
Всего: 44





--------------------
Что бы понять рекурсию, надо понять рекурсию

"Профессионал - это человек сделавший все возможные ошибки в очень узкой области". Н.Бор
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0886 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.