Чем заменить if () else if() else if() else if() else...
От: Аноним  
Дата: 28.01.07 15:12
Оценка:
Вот возникла одна мысль, возможно ли так сделать господа?


uinsigned int MyHash(char *p_Str)
{

// Какой либо алгоритм хеширования строки ...

return l_Hash;
}


.....

void MyFunc(char *p_Str)

unsigned int l_State = MyHash(p_Str);

switch(l_State)
{
case MYHASH("command"):
{
...
}

case MYHASH("event"):
{
...
}

case MYHASH("tram-ta-ra-ram"):
{
...
}
}

где MYHASH — макрос, который по сути делает со строкой то-же что и функция MyHash, но перед компиляцией, чтоб в case на момент компиляции уже были константы.

Если такое возможно, то как должен выглядеть такой макрос???
Re: Чем заменить if () else if() else if() else if() else...
От: Draqon  
Дата: 28.01.07 15:24
Оценка:
Здравствуйте, Аноним, Вы писали:
А>Если такое возможно, то как должен выглядеть такой макрос???

Если всё известно на этапе компиляции, то можно (теоретически) соорудить вычисление хэша с помощью темплейтов.
Курить товарища Александреску.
Re: Чем заменить if () else if() else if() else if() else...
От: Erop Россия  
Дата: 28.01.07 15:36
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Если такое возможно, то как должен выглядеть такой макрос???


1) Вообще говоря мне кажется, что if() {} else if(){} else if() {} else {} читабельнее. И зачем с этим бороться -- не понятно...
2) Конечно может так статься, что список длинный, обработчики сложные, а место критичное по времени. Но тогда мне больше нравится заводить объект-механизм, в котором есть регистратор обработчика по ключу, выглядит это как-то так:

namespace {
class CMySwitch : public CSwitchProcessor<TKeyType> {
public:
    CMySwitch( TArg1, TArg2 );
    
    TRes GetResult();

    void ProcessKey1() { // do sthing; }
    void ProcessKey2() { // do sthing; }
    void ProcessKey3() { // do sthing; }

private:
    TArg1 arg1;
    TArg2 arg2;
    TRes result;
};

CMySwitch::OnCase key1( key1literal, ProcessKey1 );
CMySwitch::OnCase key2( key1litera2, ProcessKey2 );
CMySwitch::OnCase key3( key1litera3, ProcessKey3 );
CMySwitch::OnCase key4( key1litera4, ProcessKey3 );
}

TRes foo( TKey key, TArg1 arg1, TArg2 arg2 )
{
    CMySwitch processor( arg1, arg2 );
    processor.Switch( key );
    return processor.GetResult():
}
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: Чем заменить if () else if() else if() else if() else
От: Erop Россия  
Дата: 28.01.07 15:54
Оценка:
Здравствуйте, Draqon, Вы писали:

D>Если всё известно на этапе компиляции, то можно (теоретически) соорудить вычисление хэша с помощью темплейтов.

D>Курить товарища Александреску.

Два вопроса.
1) А как может быть не известно на этапе компиляции, если ты хочешь привесить к ключам обработчики?
2) Зачем всё делать так сложно? Может тогда уж лучше завести какую-то свою конструкцию и того, препроцессировать внешним инструментом?
Всё-таки проще как-то будет и понятнее.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: Чем заменить if () else if() else if() else if() else
От: Draqon  
Дата: 28.01.07 16:15
Оценка: +1
Здравствуйте, Erop, Вы писали:

E>2) Зачем всё делать так сложно? Может тогда уж лучше завести какую-то свою конструкцию и того, препроцессировать внешним инструментом?

E>Всё-таки проще как-то будет и понятнее.

Тоже вариант, и тоже не идеален. Я просто отвечал на вопрос, я не утверждаю, что именно так и нужно делать
Re: Чем заменить if () else if() else if() else if() else...
От: Zigmar Израиль  
Дата: 28.01.07 17:19
Оценка: +2
Здравствуйте, Аноним, Вы писали:
А>unsigned int l_State = MyHash(p_Str);

А>switch(l_State)

А>{
А> case MYHASH("command"):
А> {
А> ...
А> }

А> case MYHASH("event"):

А> {
А> ...
А> }

А> case MYHASH("tram-ta-ra-ram"):

А> {
А> ...
А> }
А>}

А>где MYHASH — макрос, который по сути делает со строкой то-же что и функция MyHash, но перед компиляцией, чтоб в case на момент компиляции уже были константы.


Я не знаю конкретной задачи, но у меня большинство "свичей" личились простым диспачером вроде:
hash_map<string,boost::function<void (const string&)> > dispatchTable



Соотвественно сам свитч выглядит как:
dispatchTable[string](string);


плюс регистрация хендлеров:
void handleSomething(const std::string&);
class MyClass {
   Dispatcher _dispatcher;
   
   void handleThis(const std::string&);
   void handleThat();
   void handleFewThings(const std::string&);
public:
  MyClass() {
    dispatcher.addHandler("command",handleSomething);
    dispatcher.addHandler("event",boost::bind(&handleThis,this,_1));
    dispatcher.addHandler("info",boost::bind(&handleThat,this));
    dispatcher.addHandler("tram-ta-ra-ram",boost::bind(&handleFewThings,this,_1));
    dispatcher.addHandler("tram-bom-bom"  ,boost::bind(&handleFewThings,this,_1));
    dispatcher.addHandler("kuuu"          ,boost::bind(&handleFewThings,this,_1));
  }
};
"To protect people you must slay people. To let people live you must let people die. This is the true teaching of the sword."
-Seijuro Hiko, "Rurouni Kensin"
Re: Ну блин совесть есть?
От: c-smile Канада http://terrainformatica.com
Дата: 29.01.07 01:31
Оценка:
Здравствуйте, Аноним, Вы писали:

Поиск: "Чем заменить if () else if() else"
Re: Чем заменить if () else if() else if() else if() else...
От: Кирилл Лебедев Россия http://askofen.blogspot.com/
Дата: 29.01.07 20:22
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Вот возникла одна мысль, возможно ли так сделать господа?


Можно использовать std::map<> от std::string.

А вообще на эту тему есть статья "Освобождение узников оператора IF"
С уважением,
Кирилл Лебедев
Software Design blog — http://askofen.blogspot.ru/