Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Вызов функции по её названию записанному в String 
V
    Опции темы
Dimitriy
Дата 5.3.2008, 12:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Есть название функции записанное в переменной Ansi String, как можно вызвать эту функцию:

String func = "sin";
float value = 0.1;
.............................
double a = func(value);

Должна сработать функция: double a = sin(0.1);

Конечно так работать не будет, просто незнаю как обьяснить правильно, написал как смог.

Хелп плиз! Очень надо! Все мозги себе расплавил уже.

Это сообщение отредактировал(а) Dimitriy - 5.3.2008, 12:42
PM MAIL WWW ICQ   Вверх
Fazil6
Дата 5.3.2008, 12:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

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



примерно вот так
Код

#include <map>

typedef double (*FunType)(double);
typedef std::map<String , FunType> FunRegistry;


FunRegistry fr;
fr["sin"] = sin;

............

String func = "sin";
float value = 0.1;


FunRegistry::iterator pfun = fr.find(func);

if( pfun == fr.end() )
{
   ShowMessage("Error!!!!! " + func + " not registered!!!");
}
else
{
     pfun->second(value);
}

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

Это сообщение отредактировал(а) Fazil6 - 5.3.2008, 12:51
PM MAIL   Вверх
Dimitriy
Дата 5.3.2008, 13:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Fazil6? пасиб что откликнулись.

написал ваш код, ошибка выскочила, на картинке которая:

эту строку прожевать не может fr["sin"] = sin;

Это сообщение отредактировал(а) Dimitriy - 5.3.2008, 13:04

Присоединённый файл ( Кол-во скачиваний: 13 )
Присоединённый файл  ______.JPG 14,26 Kb
PM MAIL WWW ICQ   Вверх
Fazil6
Дата 5.3.2008, 13:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

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



Цитата(Dimitriy @  5.3.2008,  12:01 Найти цитируемый пост)
написал ваш код, ошибка выскочила, на картинке которая:

ну покажи что ты там и куда написал

Добавлено через 1 минуту и 32 секунды
объявление sin подключено в этом месте?
PM MAIL   Вверх
Dimitriy
Дата 5.3.2008, 13:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



ну вот весь код:

Код

//$$---- Form CPP ----
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop
#include "math.h"
#include "Unit7.h"
#include <map>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm7 *Form7;

typedef double (*FunType)(double);
typedef std::map<String , FunType> FunRegistry;

FunRegistry fr;
//fr = sin;                //Тут я уже наисправлял, раньше было как у вас, и вылетала ошибка
//---------------------------------------------------------------------------
__fastcall TForm7::TForm7(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm7::Button1Click(TObject *Sender)
{
String func = "sin";
float value = 0.1;


FunRegistry::iterator pfun = fr.find(func);

if( pfun == fr.end() )
{
   ShowMessage("Error!!!!! " + func + " not registered!!!");
}
else
{
     pfun->second(value);

}
}
//---------------------------------------------------------------------------



Это сообщение отредактировал(а) Dimitriy - 5.3.2008, 13:13
PM MAIL WWW ICQ   Вверх
Fazil6
Дата 5.3.2008, 13:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

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



Цитата(Dimitriy @  5.3.2008,  12:10 Найти цитируемый пост)
//Тут я уже наисправлял, раньше было как у вас, и вылетала ошибка

потому что надо это делать в функции какой-то.
Код

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
#include <map>
#include <math>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"

TForm1 *Form1;

typedef double (*FunType)(double);
typedef std::map<String , FunType> FunRegistry;

FunRegistry fr;

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{

    String func = "sin";
    float value = 0.1;

    fr[func] = sin;

    FunRegistry::iterator pfun = fr.find(func);

    if( pfun == fr.end() )
    {
        ShowMessage("Error!!!!! " + func + " not registered!!!");
    }
    else
    {
        pfun->second(value);
    }
}
//---

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


Новичок



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

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



ну вопщем то заработало!

у меня вот какая задача была, есть текстовый файл, в нем записаны функции(sin,cos,tan... итд),
из этого файла берутся названия функций и запускаются.

ну, возможно до меня не дошло smile , но вашим кодом так сделать не получается, если я меняю значение String func = "sin"; на String func = "cos"; срабатывает всёравно та функция которая записана тут fr[func] = sin;

незнаю, возможно сдесь
Цитата

это вариант, когда все интересуемые функции имеют одинаковую сигнатуру.

вы об этом и говорили smile 
PM MAIL WWW ICQ   Вверх
Fazil6
Дата 5.3.2008, 14:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

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



Цитата(Dimitriy @  5.3.2008,  12:55 Найти цитируемый пост)
у меня вот какая задача была, есть текстовый файл, в нем записаны функции(sin,cos,tan... итд),из этого файла берутся названия функций и запускаются.


Цитата(Dimitriy @  5.3.2008,  12:55 Найти цитируемый пост)
но вашим кодом так сделать не получается, если я меняю значение String func = "sin"; на String func = "cos"; срабатывает всёравно та функция которая записана тут fr[func] = sin;


я тебе показал как сопоставить имя функции и функцию.
Код

FunRegistry fr;

это реестр в который заносятся функции в соответствии с их именами.
под какими ты именами в него заносишь функции, по таким именам их потом и можно будет вызвать. Допустим тебе надо вызывать функции sin,cos и tan , получая информауию о том какую функцию вызвать из твоего файла. Сначала нужно сформировать реестр с именами, которые используются в твоих входных данных

Код

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
#include <map>
#include <math>
#include <sstream>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"

TForm1 *Form1;

typedef double (*FunType)(double);
typedef std::map<String , FunType> FunRegistry;

FunRegistry fr;



void CreateRegistry( FunRegistry &r )
{
      r["sin"] = sin; // сохраняем указатель на функцию sin под именем "sin"
      r["cos"] = cos;
      r["tan"] = tan;
      // и т.д.
}



FunType GetFunc( const String &name, const FunRegistry &r )
{
     FunRegistry::const_iterator pfun = fr.find(name);

    if( pfun == fr.end() )
    {
        std::ostringstream s;
        s << "Error!!!!! \"" << name.c_str() << "\" not registered!!!" ;
        throw std::runtime_error(s.str());
    }
    else
    {
        return pfun->second;
    }
}


//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
       CreateRegistry( fr ) ;
}


//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  try
  {
    String func = "sin";
    double arg = 0.1;
    FunType f = GetFunc("sin", fr );
    ShowMessage( f(arg) );

    f =  GetFunc("cos", fr );
    ShowMessage( f(arg) );

    f =  GetFunc("tan", fr );
    ShowMessage( f(arg) );

    f =  GetFunc("acos", fr );
    ShowMessage( f(arg) );
  }
  catch(const std::exception &e)
  {
    ShowMessage( e.what() );
  }

}
//---------------------------------------------------------------------------


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


Новичок



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

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



пасиб за код, работает, буду ща вставлять в прогу. 


По идее сначало предполагалось в что файл содержит не одни и те же функции, для того и делался файл, чтобы в нем можно было менять имена функций, код программы оставался прежним. 
Ну пока так поставлю.
PM MAIL WWW ICQ   Вверх
Fazil6
Дата 5.3.2008, 15:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

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



Цитата(Dimitriy @  5.3.2008,  14:03 Найти цитируемый пост)
По идее сначало предполагалось в что файл содержит не одни и те же функции, для того и делался файл, чтобы в нем можно было менять имена функций

ну так делаешь в реестре все возможные, а вызываешь только те, которые есть в файле
PM MAIL   Вверх
andrew_121
Дата 5.3.2008, 16:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

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



Это можно реализовать с помощь шаблонов. Пример:

LibSigC++


Это сообщение отредактировал(а) andrew_121 - 5.3.2008, 16:06

Присоединённый файл ( Кол-во скачиваний: 7 )
Присоединённый файл  slot.h 30,59 Kb


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
Vyacheslav
Дата 5.3.2008, 20:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

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



Продублировать эти функции в published секции формы и вызывать по имени 
http://bcdev.narod.ru/Code.htm#GetProcName3


--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


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

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


 




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


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

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