Re[4]: Проверить тип void*
От: enji  
Дата: 04.01.14 13:25
Оценка:
Здравствуйте, jazzer, Вы писали:

J>А почему бы в таком случае не использовать boost::function напрямую (или вообще boost::signal)? Он шаблонов не требует, у него тип нормальный, а в замыкание при конструировании что угодно можно засунуть, не нужно никаких дополнительных void*-параметров.


велосипедостроение потому что boost::signal напрямую использовать не получится — хочется фильтрацию и приоритеты вызовов. function кушает 16 байт и дает вызов по указателю на член + вызов виртуальной функции. Мои два указателя кушают 8 байт и дают простой вызов функции по указателю. Хотя конечно function значительно более удобен для оборачивания всяких лямбд. Может быть и перееду в конце концов на него.

Однако к первоначальному вопросу это отношения не имеет — хотелось определять тип источника сигнала и предпринимать некоторые действия в зависимости от этого.

Судя по этой теме, никакой волшебной пули нет — или надо в качестве источника иметь некий объект с доп информацией, или внешний реестр источников.
Re[5]: Проверить тип void*
От: jazzer Россия Skype: enerjazzer
Дата: 04.01.14 13:52
Оценка: 1 (1)
Здравствуйте, enji, Вы писали:

E>Здравствуйте, jazzer, Вы писали:


J>>А почему бы в таком случае не использовать boost::function напрямую (или вообще boost::signal)? Он шаблонов не требует, у него тип нормальный, а в замыкание при конструировании что угодно можно засунуть, не нужно никаких дополнительных void*-параметров.


E>велосипедостроение потому что boost::signal напрямую использовать не получится — хочется фильтрацию и приоритеты вызовов. function кушает 16 байт и дает вызов по указателю на член + вызов виртуальной функции. Мои два указателя кушают 8 байт и дают простой вызов функции по указателю. Хотя конечно function значительно более удобен для оборачивания всяких лямбд. Может быть и перееду в конце концов на него.


Если ты знаешь, какие типы могут быть, и при этом не хочешь наследовать все от одного базового типа, но знаешь все возможные базы — попробуй boost::variant с этим набором возможных базовых типов.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[4]: Проверить тип void*
От: TarasB  
Дата: 04.01.14 18:41
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Нет, нельзя. dynamic_cast мог бы, но он не работает с void*, ему нужен указатель на объект реального класса.


Ну так подсунь ему не void* а BasicRootClassOfAllClasses, все нужные классы наследуй от него.
Re[5]: Проверить тип void*
От: jazzer Россия Skype: enerjazzer
Дата: 05.01.14 10:38
Оценка:
Здравствуйте, TarasB, Вы писали:

TB>Здравствуйте, jazzer, Вы писали:


J>>Нет, нельзя. dynamic_cast мог бы, но он не работает с void*, ему нужен указатель на объект реального класса.


TB>Ну так подсунь ему не void* а BasicRootClassOfAllClasses, все нужные классы наследуй от него.


у него там int в примере есть, как нафиг BasicRootClassOfAllClasses
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[6]: Проверить тип void*
От: TarasB  
Дата: 05.01.14 11:02
Оценка:
Здравствуйте, jazzer, Вы писали:

J>у него там int в примере есть, как нафиг BasicRootClassOfAllClasses


Пусть обернёт в класс тогда этот свой инт.
Re[7]: Проверить тип void*
От: jazzer Россия Skype: enerjazzer
Дата: 05.01.14 11:23
Оценка:
Здравствуйте, TarasB, Вы писали:

TB>Здравствуйте, jazzer, Вы писали:


J>>у него там int в примере есть, как нафиг BasicRootClassOfAllClasses


TB>Пусть обернёт в класс тогда этот свой инт.


Зачем?
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[8]: Проверить тип void*
От: TarasB  
Дата: 05.01.14 12:01
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Зачем?


Чтобы отличить указатель на Int от указателя на Base. Ну, если ему это нужно. Если не нужно, то к чему твоё замечание про int?
Re: Проверить тип void*
От: Кодт Россия  
Дата: 05.01.14 14:01
Оценка: 1 (1)
Здравствуйте, enji, Вы писали:

E>Хочется узнать, указывает ли void* на конкретный тип

E>По идее можно проверить vptr, но к нему кроскомпиляторно не подберешься, да и всякие случаи вроде множественного наследования...

В общем случае, это невозможно, void* — это слишком хорошо стёртый тип. Особенно, с учётом того, что можно взять указатель на неполиморфную базу полиморфного наследника — она ничем не отличается от члена-данного, кроме тайного знания, что это не член, а база.

Если класс полиморфный, то обычная практика — поместить vfptr в самое начало лэяута. (Это не оговаривается стандартом, так же, как не оговаривается вообще механизм виртуальных функций и rtti; но MS- и linux-совместимые компиляторы делают именно так).
При этом неполиморфные базы смещаются, а если есть несколько полиморфных баз — то первая из них будет с нулевым смещением, а остальные со своими vfptr-ами — как придётся.

(Тут я хотел написать много слов про dynamic_cast, в том числе про dynamic_cast<void*>, но проще будет отослать к первоисточникам и толкованиям — стандарту и Страуструпу).

Разумеется, dynamic_cast применительно к неполиморфным объектам — это неопределённое поведение. Потому что, представьте себе, что там по нулевому смещению находится указатель на какую-нибудь мусорную таблицу виртуальных функций. Можно получить всё, что угодно, от защиты памяти до исполнения произвольного кода.

Отсюда мораль
— или сдерживать себя и ограничиться какой-нибудь строгой иерархией (не void*, а MyRootType*)
— или сделать внешнюю информацию о типе — хоть boost::any, хоть tagVARIANT рядом держать, — способов много
Перекуём баги на фичи!
Re[5]: Проверить тип void*
От: Erop Россия  
Дата: 07.01.14 12:28
Оценка:
Здравствуйте, enji, Вы писали:

E>велосипедостроение потому что boost::signal напрямую использовать не получится — хочется фильтрацию и приоритеты вызовов. function кушает 16 байт и дает вызов по указателю на член + вызов виртуальной функции. Мои два указателя кушают 8 байт и дают простой вызов функции по указателю. Хотя конечно function значительно более удобен для оборачивания всяких лямбд. Может быть и перееду в конце концов на него.


Если источники сигнала всегда приходят типизированными, и только внутри твоей библиотеки заворачиваются в void*, то можно всегда брать их внутрь шаблонным методом/конструктором и класть рядом с void* указатель на шаблонную реализацию интерфейса, через котрый можно всё разрулить...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.