Уменьшение количества кода if / if (C ++) - PullRequest
4 голосов
/ 22 января 2011

В моей программе мне нужно создать объект, который выглядит следующим образом:

Library::Param1<Library::Param2>::Param3 (не знаю, как назвать Param, возможно, типы?) Похоже на std::vector<std::string>::iterator.

Итак, эти Param должны быть изменены строками.Например:

if(param1 == "1_VALUE1")
{
    if(param2 == "2_VALUE1")
    {
        MyLib::1_VALUE1<MyLib::2_VALUE1>::Param3 obj;
        //Obj is used
    }
    //15+ similar if-statements, where only 2_VALUE1 changes
}
/*15+ similar if-statements, where only 1_VALUE1 changes,
  but the contents remain same (again 15+ if-statements)*/

using namespace MyLib; не является обязательным.

Итак, мне нужно уменьшить количество этих операторов if, но я не знаюспособ сделать это.Я думаю, что это можно сделать с помощью шаблонов, но я не знаком с ними, поэтому, я думаю, мне понадобится пример кода.

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

--- РЕДАКТИРОВАТЬ: Определения типов библиотеки (CryptoPP):

Так как ошибки есть только в Param1, публикуем один вариант этого:

Ответы [ 2 ]

3 голосов
/ 22 января 2011

Я согласен с Марком Б, что фабрика была бы хороша, но я не уверен, возможно ли это, если у вас нет базового класса, от которого наследуются все эти типы.Если я правильно понимаю проблему, у вас есть 15 типов для значения 1 и 15 типов для значения 2, что приводит к 15 * 15 операторам if.Вы можете уменьшить их до 2 * 15 следующим способом: (не проверено)

--- EDIT1: изменен порядок методов ---

template void level2 () {typename T1_T2 ::Param3 obj;йоЗотеЬЫпд (OBJ);}

template <template<class> class T1>
void level1(std::string param2)
{
 if (param2 == "2_VALUE1")
   level2<T1<MyLib::2_Value1> >();
 if (param2 == "2_VALUE1")
   level2<T1<MyLib::2_Value2> >();
 ...
}


void level0(std::string param1, std::string param2)
{
 if (param1 == "1_VALUE1")
   level1<MyLib::1_Value1>(param2);
 if (param2 == "1_VALUE2")
   level1<MyLib::1_Value2>(param2);
 ...
}

--- EDIT2 ---

Чтобы помочь вам понять, почему вы не можете компилировать, вы можете начать с этого примера кода (компилируется в Visual Studio 2008):

void doSomething(int x)
{
}

struct Type2_1 {};

template <class T2>
struct Type1_1
{
    typedef int Param3;
};

template <class T2>
struct Type1_2
{
    typedef int Param3;
};

template <template<class> class T1>
void level1(std::string param2)
{
 if (param2 == "2_VALUE1")
   level2<T1<Type2_1> >();
}

void level0(std::string param1, std::string param2)
{
 if (param1 == "1_VALUE1")
   level1<Type1_1>(param2);
 if (param2 == "1_VALUE2")
   level1<Type1_2>(param2);
}

template <class T1_T2>
void level2()
{
  typename T1_T2::Param3 obj;
  doSomething(obj);
}

int main(int argc, char* argv[])
{
  level0("1_VALUE1", "2_VALUE1");
  return 0;
}

Обратите внимание, что doSomething () должен быть тем, что вы хотите, чтобы MyLib делал с вашим obj;Возвращение obj с уровня 0/1/2 не будет работать без базового класса.

0 голосов
/ 22 января 2011

Вместо динамического изменения типа с использованием таких операторов if, как этот, что не очень хорошо поддерживается в C ++, рассмотрите возможность использования чего-то вроде заводского шаблона.

В основном вы устанавливаетесоставить иерархию классов с виртуальными методами, которые реализуют то, что вы пытаетесь сделать в случаях if.Затем вы создаете функцию, которая создает соответствующий дочерний класс из набора строк, а затем вызываете go или что-то еще в созданном экземпляре.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...