| указатель на мембер | |
| От: | night beast | ||
| Дата: | 10.08.06 06:25 |
| Недавно столкнулся с такой непонятной штукой. Указатель на мембер-функцию не является указателем.
Какие причины такого решения? |
| Re: указатель на мембер | |
| От: | Bell | ||
| Дата: | 10.08.06 07:17 | ||
| Оценка: | +1 | ||
| Здравствуйте, night beast, Вы писали: NB>Недавно столкнулся с такой непонятной штукой. NB>Указатель на мембер-функцию не является указателем. Да, это более сложная сущность. NB>Какие причины такого решения? Ну хотя бы то, что размеры указателя и указателя на член в общем случае не совпадают. Любите книгу — источник знаний (с) М.Горький |
| Re[2]: указатель на мембер | |
| От: | shank | ||
| Дата: | 10.08.06 07:44 | ||
| Оценка: | +1 | ||
| Здравствуйте, Bell, Вы писали: NB>>Какие причины такого решения? B>Ну хотя бы то, что размеры указателя и указателя на член в общем случае не совпадают. Размеры указателей на int и на double тоже "в общем случае" не совпадают. --- ![]() |
| Re[2]: указатель на мембер | |
| От: | night beast | ||
| Дата: | 10.08.06 07:47 |
| Здравствуйте, Bell, Вы писали: NB>>Недавно столкнулся с такой непонятной штукой. NB>>Указатель на мембер-функцию не является указателем. B>Да, это более сложная сущность. NB>>Какие причины такого решения? B>Ну хотя бы то, что размеры указателя и указателя на член в общем случае не совпадают. ну а вот, например, размер указателя и указателя на функцию тоже не обязаны совпадать. однако для указателей на функцию все работает как надо. |
| Re[3]: указатель на мембер | |
| От: | shank | ||
| Дата: | 10.08.06 07:59 |
| Здравствуйте, night beast, Вы писали: NB>>>Какие причины такого решения? B>>Ну хотя бы то, что размеры указателя и указателя на член в общем случае не совпадают. NB>ну а вот, например, размер указателя и указателя на функцию тоже не обязаны совпадать. однако для указателей на функцию все работает как надо. Указатели (на объекты, функции, void) и указатели на нестатические члены класса относятся к разным группам типов, с т.з. стандарта, ничего здесь не поделаешь. --- ![]() |
| Re: указатель на мембер | |
| От: | zaufi | ||
| Дата: | 10.08.06 08:01 |
| Здравствуйте, night beast, Вы писали: NB>Недавно столкнулся с такой непонятной штукой. NB>Указатель на мембер-функцию не является указателем. NB>
добавь выделенную специализацию... в общем случае нада заспециализироваться для функций с 1,2,3,...,N параметрами... |
| Re[2]: указатель на мембер | |
| От: | night beast | ||
| Дата: | 10.08.06 08:05 |
| Здравствуйте, zaufi, Вы писали: NB>>Недавно столкнулся с такой непонятной штукой. NB>>Указатель на мембер-функцию не является указателем. Z>добавь выделенную специализацию... Z>в общем случае нада заспециализироваться для функций с 1,2,3,...,N параметрами... именно! приходится плодить кучу специализаций на ровном месте (добавь еще к ним указатель на постоянную мембер функцию) это нормально по вашему? |
| Re[4]: указатель на мембер | |
| От: | night beast | ||
| Дата: | 10.08.06 08:08 |
| Здравствуйте, shank, Вы писали: S>Указатели (на объекты, функции, void) и указатели на нестатические члены класса относятся к разным группам типов, с т.з. стандарта, ничего здесь не поделаешь. дело в том, что указатель на функцию в общем случае не может быть преобразован к указателю на void (что справедливо для обычных объектов). и в этом плане он не отличается от указателя на мембер. |
| Re[3]: указатель на мембер | |
| От: | jazzer | ||
| Дата: | 10.08.06 08:19 |
| Здравствуйте, night beast, Вы писали: Z>>в общем случае нада заспециализироваться для функций с 1,2,3,...,N параметрами... NB>именно! NB>приходится плодить кучу специализаций на ровном месте (добавь еще к ним указатель на постоянную мембер функцию) NB>это нормально по вашему? ну а попробуй написать просто is_pointer_to_function, без функций-членов — получишь то же самое. Хотя, может быть, тут удастся извратиться методом исключения, но не суть.
|
| Re[5]: указатель на мембер | |
| От: | shank | ||
| Дата: | 10.08.06 08:21 |
| Здравствуйте, night beast, Вы писали: NB>дело в том, что указатель на функцию в общем случае не может быть преобразован к указателю на void (что справедливо для обычных объектов). Кстати такое преобразование, по идее, должно давать ошибку компиляции (даже если используются reinterpret_cast или c-cast). NB>и в этом плане он не отличается от указателя на мембер. Я о другом, указатель на функцию является "просто" указателем (pointer), как и указатели на объекты, тогда как указатель на функцию-член — это pointer-to-member, совершенно другая группа типов. --- ![]() |
| Re[4]: указатель на мембер | |
| От: | night beast | ||
| Дата: | 10.08.06 08:26 |
| Здравствуйте, jazzer, Вы писали: Z>>>в общем случае нада заспециализироваться для функций с 1,2,3,...,N параметрами... NB>>именно! NB>>приходится плодить кучу специализаций на ровном месте (добавь еще к ним указатель на постоянную мембер функцию) NB>>это нормально по вашему? J>ну а попробуй написать просто is_pointer_to_function, без функций-членов — получишь то же самое. J>Хотя, может быть, тут удастся извратиться методом исключения, но не суть. да. но вопрос то в другом. тот код отлично работает для указателей на функцию без специализаций. вот и интересуюсь, в чем причина. |
| Re[3]: указатель на мембер | |
| От: | zaufi | ||
| Дата: | 10.08.06 08:31 |
| Здравствуйте, night beast, Вы писали: NB>Здравствуйте, zaufi, Вы писали: NB>>>Недавно столкнулся с такой непонятной штукой. NB>>>Указатель на мембер-функцию не является указателем. Z>>добавь выделенную специализацию... Z>>в общем случае нада заспециализироваться для функций с 1,2,3,...,N параметрами... NB>именно! NB>приходится плодить кучу специализаций на ровном месте (добавь еще к ним указатель на постоянную мембер функцию) NB>это нормально по вашему? если ломно заморачиваться используй boost::type_traits -- не изобретай велосипед... все уже сделано давно до тебя! -- а вообще такая проблема лекго решается препроцессором генерящим для тебя нужное количество требуемых специализаций (для чего также удобно использовать BOOST_PP_... макросы |
| Re[6]: указатель на мембер | |
| От: | night beast | ||
| Дата: | 10.08.06 08:34 |
| Здравствуйте, shank, Вы писали: NB>>и в этом плане он не отличается от указателя на мембер. S>Я о другом, указатель на функцию является "просто" указателем (pointer), как и указатели на объекты, тогда как указатель на функцию-член — это pointer-to-member, совершенно другая группа типов. "просто" указатель -- низкоуровневая абстракция. вот лично ты видишь логические основания не считать pointer-to-member указателем? |
| Re[7]: указатель на мембер | |
| От: | valker | ||
| Дата: | 10.08.06 08:43 |
| Здравствуйте, night beast, Вы писали: NB>"просто" указатель -- низкоуровневая абстракция. NB>вот лично ты видишь логические основания не считать pointer-to-member указателем? При прочтеннии этой ветки пришла такая мысль, почему бы не трактовать функции-члены, как обычные функции, но с дополнительным параметром в начале списка — аналогом this, передающимся неявно. код мог бы быть таким:
Posted using RSDN@HOME |
| Re[4]: указатель на мембер | |
| От: | night beast | ||
| Дата: | 10.08.06 08:46 |
| Здравствуйте, zaufi, Вы писали: NB>>именно! NB>>приходится плодить кучу специализаций на ровном месте (добавь еще к ним указатель на постоянную мембер функцию) NB>>это нормально по вашему? Z>если ломно заморачиваться используй boost::type_traits -- не изобретай велосипед... все уже сделано давно до тебя! не ломило Автор: night beast )Дата: 07.08.06 это просто одна из иллюстраций проблемы. вот еще:
Z>-- Z>а вообще такая проблема лекго решается препроцессором генерящим для тебя нужное количество требуемых специализаций Z>(для чего также удобно использовать BOOST_PP_... макросы "кто сказал что микроскопом нельзя забивать гвозди? главное колотить сильнее" (с) не хорошо это, не красиво. |
| Re[8]: указатель на мембер | |
| От: | zaufi | ||
| Дата: | 10.08.06 08:47 | ||
| Оценка: | ![]() | ||
| Здравствуйте, valker, Вы писали: V>Здравствуйте, night beast, Вы писали: NB>>"просто" указатель -- низкоуровневая абстракция. NB>>вот лично ты видишь логические основания не считать pointer-to-member указателем? V>При прочтеннии этой ветки пришла такая мысль, почему бы не трактовать функции-члены, как обычные функции, но с дополнительным параметром в начале списка — аналогом this, передающимся неявно. V>код мог бы быть таким: V>
твою мысль украли бустеры ужа давно -- и использовали при реализации boost::bind |
| Re[3]: указатель на мембер | |
| От: | kan_izh | ||
| Дата: | 10.08.06 08:54 |
| shank wrote: > NB>>Какие причины такого решения? > B>Ну хотя бы то, что размеры указателя и указателя на член в общем > случае не совпадают. Совпадают. Posted via RSDN NNTP Server 2.0 но это не зря, хотя, может быть, невзначай гÅрмония мира не знает границ — сейчас мы будем пить чай |
| Re[9]: указатель на мембер | |
| От: | valker | ||
| Дата: | 10.08.06 08:56 |
| Здравствуйте, zaufi, Вы писали: Z> Z>твою мысль украли бустеры ужа давно -- и использовали при реализации boost::bind Ух, ворюги!!! Мой вопрос был: почему это не сделано на уровне языка? Вроде бы препятствий нет. Или я их не вижу? Posted using RSDN@HOME |
| Re[3]: указатель на мембер | |
| От: | Bell | ||
| Дата: | 10.08.06 09:03 | ||
| Оценка: | 1 (1) | ||
| Здравствуйте, shank, Вы писали: S>Здравствуйте, Bell, Вы писали: NB>>>Какие причины такого решения? B>>Ну хотя бы то, что размеры указателя и указателя на член в общем случае не совпадают. S>Размеры указателей на int и на double тоже "в общем случае" не совпадают. Неужели? Любите книгу — источник знаний (с) М.Горький |
| Re[4]: указатель на мембер | |
| От: | shank | ||
| Дата: | 10.08.06 09:16 | ||
| Оценка: | 17 (3) | ||
| Здравствуйте, Bell, Вы писали: S>>Размеры указателей на int и на double тоже "в общем случае" не совпадают. B>Неужели? Угу. Единственное, что гарантируется касательно размеров указателей, это то, что размер void* достаточен для того, чтобы "вместить" указатель на объект любого типа, а также то что sizeof(void*) == sizeof(char*). Больше никаких гарантий. (Это объяснялось где-то Steve'ом Clamage'ом, если мне склероз не изменяет).
--- ![]() |
| Re[8]: указатель на мембер | |
| От: | Dmitry Kotlyarov | ||
| Дата: | 10.08.06 12:46 |
| Здравствуйте, valker, Вы писали: V>При прочтеннии этой ветки пришла такая мысль, почему бы не трактовать функции-члены, как обычные функции, но с дополнительным параметром в начале списка — аналогом this, передающимся неявно. Такой метод использовал Страуструп во времена, когда в C++ еще не было указателей на члены, а они ему были нужны. Потом он ушел от этого, определив в языке такой тип как "указатель на член", тем самым сделав систему типов более логичной. Подробнее см. "Дизайн и эволюция C++". |
| Re[7]: указатель на мембер | |
| От: | Аноним 458 | ||
| Дата: | 11.08.06 14:43 |
| Здравствуйте, night beast, Вы писали: NB>Здравствуйте, shank, Вы писали: NB>>>и в этом плане он не отличается от указателя на мембер. S>>Я о другом, указатель на функцию является "просто" указателем (pointer), как и указатели на объекты, тогда как указатель на функцию-член — это pointer-to-member, совершенно другая группа типов. NB>"просто" указатель -- низкоуровневая абстракция. NB>вот лично ты видишь логические основания не считать pointer-to-member указателем? Скажем так: "просто указатель" — это смещение в некотором хранилище, по которому находится некоторый объект. pointer-to-member — это смещение члена от смещения в некотором хранилище, по которому находится некоторый объект. Код ф-ии члена хранится только в одном месте, делая похожей ф-ию-член на обычную. Следовательно можно было бы использовать "просто указатель" на ф-ию-член. Однако это абсолютно не работает по отношению к членам-данным (см.определения выше). Поэтому создали универсальную сущность pointer-to-member... Личное мнение — неудобств это не вызывает, а четко отделенное понятие упрощает понимание. |
| Re[8]: указатель на мембер | |
| От: | night beast | ||
| Дата: | 12.08.06 03:10 |
| Здравствуйте, Аноним, Вы писали: А>Код ф-ии члена хранится только в одном месте, делая похожей ф-ию-член на обычную. Следовательно можно было бы использовать "просто указатель" на ф-ию-член. Однако это абсолютно не работает по отношению к членам-данным (см.определения выше). Поэтому создали универсальную сущность pointer-to-member... Я не против того что это отдельная сущьность. Мне не удобно что у этой сущьности поведение отличается от поведения похожих сущьностей. А>Личное мнение — неудобств это не вызывает, а четко отделенное понятие упрощает понимание. Не вызавает когда пользуешься не часто. http://www.rsdn.ru/Forum/Message.aspx?mid=2051884&only=1 Автор: night beast .Дата: 10.08.06 |
| Re[5]: указатель на мембер | |
| От: | Аноним 768 | ||
| Дата: | 01.08.09 18:18 |
| Здравствуйте, night beast, Вы писали: NB>Здравствуйте, shank, Вы писали: S>>Указатели (на объекты, функции, void) и указатели на нестатические члены класса относятся к разным группам типов, с т.з. стандарта, ничего здесь не поделаешь. NB>дело в том, что указатель на функцию в общем случае не может быть преобразован к указателю на void (что справедливо для обычных объектов). NB>и в этом плане он не отличается от указателя на мембер. Гляньте пример в Detours. ////////////////////////////////////////////////////////////////////////////// // // Test a detour of a member function (member.cpp of member.exe) // // Microsoft Research Detours Package, Version 2.1. // // Copyright (c) Microsoft Corporation. All rights reserved. // // By default, C++ member functions use the __thiscall calling convention. // In order to Detour a member function, both the trampoline and the detour // must have exactly the same calling convention as the target function. // Unfortunately, the VC compiler does not support a __thiscall, so the only // way to create legal detour and trampoline functions is by making them // class members of a "detour" class. // // In addition, C++ does not support converting a pointer to a member // function to an arbitrary pointer. To get a raw pointer, the address of // the member function must be moved into a temporrary member-function // pointer, then passed by taking it's address, then de-referencing it. // Fortunately, the compiler will optimize the code to remove the extra // pointer operations. // // If X::Target is a virtual function, the following code will *NOT* work // because &X::Target is the address of a thunk that does a virtual call, // not the real address of the X::Target. You can get the real address // of X::Target by looking directly in the VTBL for class X, but there // is no legal way to 1) get the address of X's VTBL or 2) get the offset // of ::Target within that VTBL. You can of course, figure these out for // a particular class and function, but there is no general way to do so. Там преобразование идет через & (PVOID &) |
| Re[8]: указатель на мембер | |
| От: | Programador | ||
| Дата: | 02.08.09 10:10 |
| Здравствуйте, Аноним, Вы писали: А>Код ф-ии члена хранится только в одном месте, делая похожей ф-ию-член на обычную. Следовательно можно было бы использовать "просто указатель" на ф-ию-член. Нельзя, чтоб позвать функцию-член нужно иметь this, а this-ы бывают разные при множественном наследовании ЕМНИП где-то преобразования this делают специальные прокладки в пару команд, так что и код в одном месте не хранится. |
| Re[2]: указатель на мембер | |
| От: | Аноним 801 | ||
| Дата: | 06.08.09 13:03 |
| Здравствуйте, Bell, Вы писали: B>Здравствуйте, night beast, Вы писали: NB>>Недавно столкнулся с такой непонятной штукой. NB>>Указатель на мембер-функцию не является указателем. B>Да, это более сложная сущность. NB>>Какие причины такого решения? B>Ну хотя бы то, что размеры указателя и указателя на член в общем случае не совпадают. Cам разок на это натыкался и выяснил, что в .Net ++'ом компиляторе размеры совпадают, а в gcc (на тот момент под рукой был 2.9.x) нет. 2-варианты, либо реализация зависит от компилятора, либо один из них не"до"поддерживает стандарт, по части указателей на мембер классы |
| Re: указатель на мембер | |
| От: | Tilir | ||
| Дата: | 07.08.09 06:06 |
| Здравствуйте, night beast, Вы писали: NB>Недавно столкнулся с такой непонятной штукой. NB>Указатель на мембер-функцию не является указателем. NB>Какие причины такого решения? Он им и не является. Когда мы говорим "указатель на функцию", мы имеем в виду нечто сложное, учитывающее сигнатуру конкретной функции. Когда мы говорим просто "указатель", мы мгновенно получаем кучу бенефитов: дуализм с массивами, создание по указателю, адресную арифметику... всего этого мы лишаемся при "указателе на функцию". Именно поэтому специализация к T* считает, что вам нужно нечто, что является честным указателем со всей его обвязкой, чем указатель на функцию на является. Попробуйте например на вкус вот такой код:
Как вы там представляете указатель на функцию? |
| Re[2]: указатель на мембер | |
| От: | Programador | ||
| Дата: | 07.08.09 08:20 |
| Здравствуйте, Tilir, Вы писали: T>Как вы там представляете указатель на функцию? на обычную функцию указатель приводим к (void *) и обратно. Он указатель, просто сам обьект не копируем и не имеет характеристики длинны. А дуализм массив-указатель ИМХО не всегда нужен, нужен дополнительный тип мутабельная_ссылка, чтоб к типу с адресной арифметикой в явную приводилась. |
| Re[5]: указатель на мембер | |
| От: | Кодт модератор | ||
| Дата: | 07.08.09 10:18 |
| Здравствуйте, shank, Вы писали: S>>>Размеры указателей на int и на double тоже "в общем случае" не совпадают. B>>Неужели? S>Угу. S>Единственное, что гарантируется касательно размеров указателей, это то, что размер void* достаточен для того, чтобы "вместить" указатель на объект любого типа, а также то что sizeof(void*) == sizeof(char*). Больше никаких гарантий. (Это объяснялось где-то Steve'ом Clamage'ом, если мне склероз не изменяет). Чисто гипотетически, это может пригодиться для машин со слишком широким словом данных (БЭСМ-6, IBM-360, какие-нибудь современные DSP). Одно слово — один double. Машинный адрес — только пословно. Чтобы адресоваться посимвольно, нужно тащить ещё и сдвиг символа в слове. Тогда указатели на числа и на выравненные структуры данных — это адреса, а указатели на символы — это уже пара (адрес,сдвиг). Можно, конечно, пойти паскалевской дорогой, ввести тип упакованной строки... Типа, диалект для экзотической платформы. ... << RSDN@Home 1.2.0 alpha 4 rev. 1237>> Перекуём баги на фичи! |
| Re[5]: указатель на мембер | |
| От: | Vamp | ||
| Дата: | 07.08.09 13:34 | ||
| Оценка: | ![]() | ||
| Чуть-чуть пендатизма. S>...а также то что sizeof(void*) == sizeof(char*). ... В приведенной строчке надо либо убрать один знак =, либо видоизменить ее так: (sizeof(void*) == sizeof(char*)) = true Да здравствует мыло душистое и веревка пушистая. |
| Re[3]: указатель на мембер | |
| От: | Tilir | ||
| Дата: | 07.08.09 16:38 |
| Здравствуйте, Programador, Вы писали: P>на обычную функцию указатель приводим к (void *) и обратно. Он указатель, просто сам обьект не копируем и не имеет характеристики длинны. А дуализм массив-указатель ИМХО не всегда нужен, нужен дополнительный тип мутабельная_ссылка, чтоб к типу с адресной арифметикой в явную приводилась. Пока такого типа нет (и вряд ли будет), программист, особенно с опытом на C, волен ожидать от специализированного на "указатель" типа всё, что традиционно можно вытворять с указателем. Включая и то, что вам лично кажется не нужным |