Comments 46
compiler is your friend — use it often
© Кто-то из магистров =)
© Кто-то из магистров =)
+15
Ой как здорово то. Но на мой взгляд лучше просто задуматься над тем что пытаешься сделать и понять, что указатель на функцию это как ее сигнатура, но только со звездочкой.
+1
По-моему указатели на функции — это рудимент языка. Если уж речь о C++, то коли нам нужна функция как объект, то уж лучше сразу сделать из неё функциональный объект, а не мучаться с представлением в виде указателя.
+3
Указатель на функцию — по сути самый шустрый метод реализации многих вещей.
Первое что в голову приходит — коллбэки и таблицы функций.
Первое что в голову приходит — коллбэки и таблицы функций.
+3
Многих, но отнюдь не всех.
Темплейты и функторы помогают компилятору гораздо эффективней делать оптимизацию. Классический пример — qsort() в plain С vs std::sort() из С++
Темплейты и функторы помогают компилятору гораздо эффективней делать оптимизацию. Классический пример — qsort() в plain С vs std::sort() из С++
+2
Немного поправляю, для функторов компилятор создает отдельную специализацию того же std::for_each, и поэтому может встроить его тело в данную ф-цию.
В случае реализации через указатели на ф-ции, встраивание невозможно.
Конечно я не считаю время затраченное на вызов, огромным профитом, но всеже :)
В случае реализации через указатели на ф-ции, встраивание невозможно.
Конечно я не считаю время затраченное на вызов, огромным профитом, но всеже :)
+1
>> В случае реализации через указатели на ф-ции, встраивание невозможно.
невозможно в общем случае, но в частных случаях, когда значение указателя можно статически вычислить и понять, что он указывает на функцию находящуюся в одной единице трансляции, открытая подстановка становится возможной…
невозможно в общем случае, но в частных случаях, когда значение указателя можно статически вычислить и понять, что он указывает на функцию находящуюся в одной единице трансляции, открытая подстановка становится возможной…
+1
Согласен. Например, я через указатель на функции реализую программирование на машинных кодах. Т.е. забиваю массив char[] опкодами, затем привожу указатель на начало массива к указателю на функцию. Все известные мне компиляторы С++ это едят и получается некое подобие jit-compilation. Кто знаком с .NET и с тем, как реализуется компиляция байт-кода в нативный — те меня поймут.
Причем другого способа передать управление в сегмент данных не существует =)
Причем другого способа передать управление в сегмент данных не существует =)
0
Да, об этом я и вел речь, только я вспоминал ACS интерпретатор в Hexen'е первом. Я помню его оттуда позаимствовал, когда свой двухмерный аналог Hexen писал :D
0
а DEP не ругается?
0
Главное поместить код в нужную страницу и разрешить его выполнение.
Если попытаться выполнить массив из хипа — ругнется с access violation.
Если попытаться выполнить массив из хипа — ругнется с access violation.
0
Я впринципе согласен с вами, но ситуации бывают разными.
Некоторые апи могут требовать указатели на ф-ции, некоторым проектам лет по 10, некоторые код-конвеншны могут не одобрять использования темплейтс, и тд.
Цель заметки состояла не в том, что бы пропогандировать использование указателей на ф-ции, а в том что бы подсказать как можно сэкономить время и нервы некоторым программистам.
Некоторые апи могут требовать указатели на ф-ции, некоторым проектам лет по 10, некоторые код-конвеншны могут не одобрять использования темплейтс, и тд.
Цель заметки состояла не в том, что бы пропогандировать использование указателей на ф-ции, а в том что бы подсказать как можно сэкономить время и нервы некоторым программистам.
0
Да, об устаревших API не подумал, точно.
А если «код-конвеншны не одобряют использования темплейтс», то тогда это не C++, а C. Странно писать на C++ и не пользоваться темплейтами или исключениями (кстати вроде Гугл у себя запрещает искюлчения). Хотя в мире много странных вещей :)
А если «код-конвеншны не одобряют использования темплейтс», то тогда это не C++, а C. Странно писать на C++ и не пользоваться темплейтами или исключениями (кстати вроде Гугл у себя запрещает искюлчения). Хотя в мире много странных вещей :)
0
Странно, но если код к примеру не ексцепшн сейф, тогда на использование ексцепшнов логично наложить ограничения типа: не бросать из утилит и использовать их только в полностью новых и безопасных учатках кода.
Хотя в любом случае подобные ограничения меня тоже повергают в ступор, но они, к сожалению, бывают. У нас, к примеру, главный программист, который в штатах наложил вето на использование ассертов.
Хотя в любом случае подобные ограничения меня тоже повергают в ступор, но они, к сожалению, бывают. У нас, к примеру, главный программист, который в штатах наложил вето на использование ассертов.
0
У assert'ов есть несколько проблем в дизайне: во-первых, они выполняют проверки только в Debug-режиме (молчаливо подразумевая, что в Release проверок делать не надо), во-вторых, стандартное поведение assert'ов — это вызов функции abort(), которая остановит приложение. Это редко где бывает допустимо.
0
Это всё фича ассертов :)
Основная их цель проверить ошибки которые могут быть допущенны программистом.
Естественно внешние данные ассертами не стоит проверять.
Например если моя функция подразумевает (precondition), что переданный в нее вектор должен быть отсортирован, то я пишу в начале нечто вроде assert( is_sorted( v ); Это своего рода и комментарий и не замедлит работу программы в релизе.
Основная их цель проверить ошибки которые могут быть допущенны программистом.
Естественно внешние данные ассертами не стоит проверять.
Например если моя функция подразумевает (precondition), что переданный в нее вектор должен быть отсортирован, то я пишу в начале нечто вроде assert( is_sorted( v ); Это своего рода и комментарий и не замедлит работу программы в релизе.
0
Хорошо, пусть так.
Но: в релизе на вход функции могут подать не отсортированный массив? Если да — функция, получается, вернёт мусор?
Но: в релизе на вход функции могут подать не отсортированный массив? Если да — функция, получается, вернёт мусор?
0
Да, но если это не входные данные, т.е. программист не выспался и забыл отсортировать массив, мы скорее всего поймаем этот ассерт еще на стадии отладки или тестирования.
Не проверять в каждой фукнции правильность переданных параметров.
Т.е. подразумевается, что проверки на свои же ошибки писать глупо, плюс не эффективно, плюс можно погрязнуть в ифах. Но что бы улучшить себе немного жизнь — есть ассерты.
Не проверять в каждой фукнции правильность переданных параметров.
Т.е. подразумевается, что проверки на свои же ошибки писать глупо, плюс не эффективно, плюс можно погрязнуть в ифах. Но что бы улучшить себе немного жизнь — есть ассерты.
0
а оно может и верно, про ассерты. Я вот тоже, бывало, напишу ассерт, а потом думаю — «а вдруг в дебаге не сработает, а в релизе вылезет?» и пишу рядом проверку того, что в ассерте уже без ассерта. Напишу, а потом думаю — а нафига тогда я ассерт писал?
0
Рудимент ли? Конечно можно с помощью них яйца прищемить, и будет больно, но иногда они очень полезны
0
Когда же наконец в C++ появятся указатели на функции-члены произвольного класса?
0
А зачем?
0
Скорее всего, такую фишку по-простому реализовать не получится, поскольку в указателе на функцию-член класса должна храниться информация о расположении vtable относительно указателя на instance класса. Если же предположить, что у нас появился указатель на функцию-член произвольного класса, то этой информации там быть не может, следовательно, компилятор и рантайм не будет знать, как вызывать функции по таким указателям.
Я лично здесь вижу только 1 путь реализации — с добавлением RTTI на этапе взятия адреса. При взятии адреса от функции-члена в указатель будет записываться this и некая служебная информация, необходимая для вызова функции-члена (смещение vtable, или адрес метода). При вызове эта информация будет извлекаться для определения реального адреса функции-члена.
Я лично здесь вижу только 1 путь реализации — с добавлением RTTI на этапе взятия адреса. При взятии адреса от функции-члена в указатель будет записываться this и некая служебная информация, необходимая для вызова функции-члена (смещение vtable, или адрес метода). При вызове эта информация будет извлекаться для определения реального адреса функции-члена.
0
Жаль, что quick fix в Eclipse для плюсов не развит. А то можно было бы лениво писать
char func = &test::foo;Потом наводить мышкой на func и кликать в всплывающем окошке «сменить тип func» :-)
+1
От блин. А можно прочитать доки (в Страуструпе отлично), и писать все правильно, не запуская компилер, и быть уверенным что происходит.
+5
как я понимаю в c++0x проблема буде решаться просто через auto (http://www2.research.att.com/~bs/C++0xFAQ.html#auto)
+4
А что, просто скопировать заголовок функции и заменить имя на (*varname), дописав classname:: в случае функции-члена, нельзя?
0
Что не говорите, но ТАКОЕ описание указателей на функции в С/C++ мог придумать только странномыслящий субъект.
0
char c = &test::foo;Чего? О_О Вы точно это хотелось написать. По теме — известная конструкция, о которой пишут чуть ли не в каждой книге, но неудобная и плохочитаемая. В продакшн коде такое, обычно не пользуют.
0
вы вроде пропустили в последнем объявлении имя переменной с :)
0
Проблема такого подхода — это когда увидите объявление указателя (в сообщении об ошибке или коде) и не поймете на что он собственно указывает.
ГОРАЗДО лучше воспользоваться правилом «право-лево» и больше никогда не мучаться.
ГОРАЗДО лучше воспользоваться правилом «право-лево» и больше никогда не мучаться.
0
Хе… я написал сотни темплейтов, но каждый раз забываю куда там пихать угловые скобки при объявлении специализации функции… :-( Темплейтокретинизм…
0
я тоже долго не мог запомнить как объявлять указатель на функцию. :-)
0
Sign up to leave a comment.
Синтаксис объявления указателей на функции в С++