4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
1

Константы процедурного типа

14.04.2011, 11:04. Показов 2669. Ответов 19
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Под процедурным типом я понимаю тип указателя на подпрограмму, как это принято в паскале. Поддерживает ли с++ константы процедурного типа и как их декларировать? Пусть например, есть функция с прототипом
C++
1
void f();
. Как объявить константу с адресом этой функции? А лучше даже так: как в типе структуры декларировать поле типа указателя на f и как потом декларировать константный массив структур этого типа?

Добавлено через 29 минут
Так:
C++
1
2
3
4
5
6
typedef void (*voidfuntionvoid)();class TCommand
{
 public:
  char *text;
  voidfuntionvoid proc;
};
можно? Как потом объявить константный массив типа TCommand?
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
14.04.2011, 11:04
Ответы с готовыми решениями:

Разработка классов. Переделка из процедурного программирования
Имею отличный строчный калькулятор, сделанный через процедурное программирование, который мне надо...

Возврат объекта шаблонного типа от типа Type из специализации шаблона метода от того же типа
Доброго времени суток, пишу класс содержащий несколько std::set от разных типов, нужно сделать...

Как можно определить что-то типа процедурного типа или классового метода (как в Delphi)?
Подскажите: как можно определить что-то типо процедурного типа или классового метода(как в...

Процедура с параметром процедурного типа
Здравствуйте, помогите пожалуйста с решением задачи: С помощью процедуры с параметром процедурного...

19
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
14.04.2011, 11:19 2
taras atavin, Указатели на функции.
std::function/boost::function.
0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
14.04.2011, 11:42  [ТС] 3
Цитата Сообщение от ForEveR Посмотреть сообщение
Указатели на функции.
Где они подробно описаны?
Цитата Сообщение от ForEveR Посмотреть сообщение
std::function/boost::function.
Желательно всё таки без лишних прибамбасов. Если придётся лепить какую то сложную конструкцию для каждйо ветви, то где выигрыш по сравнению с ифами?
0
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
14.04.2011, 14:06 4
taras atavin, Почему все что новое и прогрессивное, не уступающее по быстродействию сразу сложное? Ни в std::function ни в boost::function ничего сложного нету.

Если это сложно - тогда конечно да.
C++
1
2
3
4
5
6
void some_foo(int)
{
}
 
std::function<void(int)> f_obj;
f_obj = some_foo;
0
Делаю внезапно и красиво
Эксперт С++
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
14.04.2011, 16:53 5
А чем обычный указатель на функцию не устраивает?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void f()
{ ... }
void f2()
{ ... }
 
typedef void (*voidfuntionvoid)();
 
class TCommand
{
 public:
    TCommand( char * name, voidfuntionvoid ptr )
      : text(name),
       proc( ptr )
    { }
 
  char *text;
  voidfuntionvoid proc;
};
 
const TCommant c[2] = { TCommand( "name", f ), TCommand( "name2" ,f2) };
С точки зрения инициализации не будет отличаться от любой другой константы.

Добавлено через 22 минуты
Хотя, лучше всё же использовать функторы. Тогда будет проще поддерживать функции с различным числом и типами параметров.
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
14.04.2011, 21:52 6
Лучший ответ Сообщение было отмечено как решение

Решение

Цитата Сообщение от ForEveR Посмотреть сообщение
Почему все что новое и прогрессивное, не уступающее по быстродействию сразу сложное?
Примерно потому: Какой язык лучше учить?

А вообще иногда оказывается, что проще объявлять не тип указателя на функцию, а просто тип функции. А при объявлении указателя добавлять звёздочку к имени переменной. Тогда с таким типом можно будет ещё и внешние функции описывать

C
1
2
3
4
5
6
7
8
9
10
11
12
typedef void (func_type_t)(int, int);
 
/* Эквивалентно extern void f1 (int, int); */
extern func_type_t f1;
 
/* Эквивалентно extern void f2 (int, int); */
extern func_type_t f2;
 
/* Константный массив из двух указателей на функцию.
 * Здесь уже рисуем явную звёздочку после типа, явным образом
 * обозначая, что это указатель */
func_type_t* const a[2] = { f1, f2 };
3
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
14.04.2011, 22:19 7
Evg, Ну не скажи. boost::function удобнее чем указатели на функции да и к тому же функциональнее + высокий уровень. По-моему в этом нет ничего плохого.
0
270 / 176 / 46
Регистрация: 12.03.2010
Сообщений: 494
14.04.2011, 22:40 8
При неумелом обращении с указателями на функции можно элементарно уложить свой процесс и сидеть ковырять в носу над дебагом. Взамен Вам предлагается готовое, стабильное решение, которое не засоряет код новыми типами.
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
14.04.2011, 22:51 9
А чтобы 2+3 сложить, тоже boost надо использовать? Или может как в линуксе, установить ещё какую-нибудь ацкую библиотеку, которая в зависимости ещё 30 других библиотек потащит. Зато 2+3 по-пацански сложим, надёжно. Я это всё к тому, что есть встроенные средства языка, а ради несчастного указателя на функцию тащить буст - это моветон

> При неумелом обращении с указателями

При кривых руках тебя и boost не спасёт
0
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
14.04.2011, 22:55 10
Evg, А std::function?)
Ну и boost::function может использоваться в разных ситуациях.

Но если для тебя важнее не удобство работы - тогда пользуйся только указателями на функции...
В таком ключе можно без проблем сказать.

Надо распарсить выражение - с реджексом все получится отлично, но тащить boost::regex в проект это моветон, поэтому будем писать свой парсер.

Надо написать некую вещь, где удобнее boost::lambda - но нееет, тащить boost::lambda это перебор.

Да и еще кучу примеров можно привести, вплоть для описания короткой грамматики, с которой лучше может справится spirit, но нет, будем лучше писать свою.
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
14.04.2011, 23:09 11
Цитата Сообщение от ForEveR Посмотреть сообщение
Надо распарсить выражение
Для тебя действительно "распарсить выражение" и "указатель на функцию" это вещи одного и того же порядка сложности? Т.е. числа складываешь ты без boost'а только потому, что в boost'е этого нет?
0
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
14.04.2011, 23:18 12
Evg, Нет не поэтому) В основном не одно и то же. Я просто привел пример, меня сильно удивляет, что в С++ ты предлагаешь использовать указатели на функции, которые в С++ никуда не впились, тем паче, что есть готовые решения, тащить boost::function в проект, если есть такая возможность - не считается моветоном. Проект на чистом С++ с использованием STL, RAII по-максимуму и вдруг создание указателя на функцию - смотрится убого, использование function - смотрится красиво и что важнее удобно. Это сейчас задача такова, что просто достаточно сделать указатель на функцию, а завтра может понадобится использовать что-то для чего без использования библиотек - придеться делать все через задницу.
Да без смысла спорить на самом деле. Каждый все равно останется при своем мнении.
0
270 / 176 / 46
Регистрация: 12.03.2010
Сообщений: 494
14.04.2011, 23:31 13
Цитата Сообщение от Evg Посмотреть сообщение
А чтобы 2+3 сложить, тоже boost надо использовать? Или может как в линуксе, установить ещё какую-нибудь ацкую библиотеку, которая в зависимости ещё 30 других библиотек потащит. Зато 2+3 по-пацански сложим, надёжно. Я это всё к тому, что есть встроенные средства языка, а ради несчастного указателя на функцию тащить буст - это моветон

> При неумелом обращении с указателями

При кривых руках тебя и boost не спасёт
Убавь громкость, дружок. Для домашнего задания поинтеров хватает с головой, а для крупного проекта такой подход выливается в качественный говнокод.
0
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
14.04.2011, 23:38 14
Evg, Ну и выражение бывает различным... Допустим надо нам проверить совпадает ли строка с паттерном пять цифр и возможны буквы в верхнем или нижнем регистре.

Можно использовать regex.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <string>
#include <regex>
 
int main()
{
    std::regex pattern("\\d{5}[a-zA-Z]*");
    std::string str;
    std::cin>>str;
    std::smatch match;
    if(std::regex_match(str, match, pattern))
        std::cout<<"Matched\n";
    else
        std::cout<<"Not matched\n";
    system("pause");
}
А можно писать что-то твое. Длиннее не будет, но на кой изобретать велосипед, когда все уже есть?
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
14.04.2011, 23:46 15
Цитата Сообщение от ForEveR Посмотреть сообщение
Проект на чистом С++ с использованием STL, RAII по-максимуму и вдруг создание указателя на функцию - смотрится убого, использование function - смотрится красиво и что важнее удобно. Это сейчас задача такова, что просто достаточно сделать указатель на функцию, а завтра может понадобится использовать что-то для чего без использования библиотек - придеться делать все через задницу.
Цитата Сообщение от Manjak Посмотреть сообщение
Для домашнего задания поинтеров хватает с головой, а для крупного проекта такой подход выливается в качественный говнокод.
Где вы большой проект увидели? Человек задал вполне конкретный вопрос: как сделать массив из указателей на функцию. Он не спрашивал, через какие нанобиблиотеки можно реализовать встроенную конструкцию языка. И не спрашивал о том, какие бы библиотеки надо затащить в проект, чтобы он не выглядел убого. Он всего лишь задал простой вопрос про указатель на функцию

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

Добавлено через 4 минуты
Цитата Сообщение от ForEveR Посмотреть сообщение
Evg, Ну и выражение бывает различным... Допустим надо нам проверить совпадает ли строка с паттерном пять цифр и возможны буквы в верхнем или нижнем регистре
В Си или в Си++ есть встроенные (в язык или в стандартную библиотечную поддержку) средства для работы с регулярными выражениями? Нет. Так зачем их сравнивать с указателями на функцию?
0
270 / 176 / 46
Регистрация: 12.03.2010
Сообщений: 494
14.04.2011, 23:50 16
Человеку давно ответили на его вопрос. Дальше пошли размышления об эстетике. Я, например, привык к чистому, стандартизированному коду по всему проекту. А если в каждом модуле есть свои тайпдефы, левые конструкции, то простоты это явно не придаст. И, в лучшем случае, мне же потом придется вспоминать что и где, а в худщем - помогать меинтейнеру раскуривать код. Если же я пишу простыми конструкциями (std::function и все остальные из стандартной библиотеки), то потом этот код будет легко поддерживаться и человеку, который захочет в нем разобраться не будут взрывать голову лишние типы.

PROFIT: код понятнее и приятнее, продуктивность труда выше, подготовка юных кадров сводится к обьяснеию архитектуры.

> В Си или в Си++ есть встроенные (в язык или в стандартную библиотечную поддержку) средства для работы с регулярными выражениями? Нет. Так зачем их сравнивать с указателями на функцию?

В С++ уже есть
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
14.04.2011, 23:58 17
Цитата Сообщение от Manjak Посмотреть сообщение
Я, например, привык .....
Это очень смахивает на то, чтобы делать таким-то образом из принципа, а не из соображений необходимости или эффективности.

Цитата Сообщение от Manjak Посмотреть сообщение
В С++ уже есть
Насколько я знаю, "текущий" стандарт Си++ - это 2003 года, а "новый" вроде бы как официально ещё не принят. Или уже принят? Если принят, то в его состав входит boost? Если не входит, то зачем пользоваться boost'ом в тех случаях, когда есть встроенные средства языка?
0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
15.04.2011, 05:49  [ТС] 18
Я не хочу парсить выражения. Берём аналогию с автокадом, там есть команда Line. Эта команда принимает координаты двух точек и проводит межеду ними отрезок, так вот, надо поддерживать
Код
Line
1, 3
40, 34
, но даже
Код
Line 1, 3, 40, 34
специально не поддерживать. И уж конечно не нужны здесь математические выражения, напрмиер,
Код
Line
1, 6/2
40, 30+4
поддерживать тоже не надо. Это конечно не аналог автокада или хотябы кукада и команды Line, да и вообще команд построения каких либо линий не будет, я просто взял для примера чужую команду, так как ещё не определился со своими.

Цитата Сообщение от ForEveR Посмотреть сообщение
Это сейчас задача такова, что просто достаточно сделать указатель на функцию, а завтра может понадобится использовать что-то для чего без использования библиотек
Библиотеки будут использоваться обязательно. Но не для этой же цели! И буст будет, но для размерных величин. И XWindows будет, а командная строка будет как в автокаде прикручена к многострочному гуёвому полю текстового ввода внизу окна и приденазначена не для того, чтоб упроалять приладой только через неё, а для дублирования меню. Но всётаки если надо где то запомнить, какую именно потом надо будет вызвать функцию, а потом вызвать её не пользуясь именем самой функции, то для этого предназначен не буст, а указатель на функцию. Какое такое удобство даст буст в этом конкретном случае?

Добавлено через 4 минуты
Цитата Сообщение от Manjak Посмотреть сообщение
А если в каждом модуле есть свои тайпдефы, левые конструкции, то простоты это явно не придаст.
Тайпдефы будут общие.
0
Делаю внезапно и красиво
Эксперт С++
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
15.04.2011, 07:42 19
Цитата Сообщение от Evg Посмотреть сообщение
typedef void (func_type_t)(int, int);
Не знал, что так тоже можно.)
0
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
15.04.2011, 07:57 20
taras atavin, Не понял.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void foo()
{
    std::cout<<"Foo\n";
}
 
void foo1()
{
    std::cout<<"Foo1\n";
}
 
void foo2()
{
    std::cout<<"Foo3\n";
}
 
int main()
{
    std::function<void(void)> arr[] = {foo, foo1, foo2};
    for(int i=0; i<sizeof(arr)/sizeof(*arr); ++i)
        arr[i]();
}
0
15.04.2011, 07:57
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
15.04.2011, 07:57
Помогаю со студенческими работами здесь

подпрограммы с параметрами процедурного типа
Решить с помощью подпрограммы с параметрами процедурного типа. Перебором с шагом 0.05 найти минимум...

Подпрограммы с параметрами процедурного типа
С погрешностью 0.001 вычислить по методу прямоугольников \int_{0}^{1}\cos...

Аналог делфийского процедурного типа в C#
в делфи можно создать переменную которая может хранить адрес процедуры и через эту переменную можно...

Подпрограммы с параметрами процедурного типа
Помогите пожалуйста написать программу... завтра зачет, а как её сделать-я не знаю..


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru