开发者

Reducing amount of if/if code (C++)

In my program I have to create an object, which looks like that:

Library::Param1<Library::Param2>::Param3 (don't know how to name Param, types maybe?) Similar to std::vector<std::string>::iterator.

So, these Param's need to be changed by strings. For example:

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; is not neseccary.

So, I need to reduce amount of those if-statements, but I do not know the way to do it. I think it could be done with templates, but I am not familiar with them, so, I guess, I would need a code sample.

Sorry for the bad english, if开发者_JS百科 any more info is needed - let me know. Thank you.

--- EDIT: Library (CryptoPP) type-definitions:

Since errors are only on Param1, posting one variation of it:

//! CBC mode with ciphertext stealing
template <class CIPHER>
struct CBC_CTS_Mode : public CipherModeDocumentation
{
 typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, CBC_CTS_Encryption> Encryption;
 typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Decryption, CBC_CTS_Decryption> Decryption;
};


I agree with Mark B that a factory would be nice, but I'm not sure if this is possible if you do not have a base class that all these types inherit from. If I understand the problem correcty, you have 15 types for Value 1 and 15 types for Value2 which leads to 15*15 if-statements. You can reduce them to 2*15 with the following approach: (untested)

---EDIT1: changed order of methods ---

template void level2() { typename T1_T2::Param3 obj; doSomething(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 ---

To help you figure out why you can't compile, you can start with this sample code (compiles on 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;
}

Please note that "doSomething()" should be whatever you want MyLib to do with your obj; Returning obj from level0/1/2 won't work without a base class.


Instead of changing the type dynamically using if statements like that, which isn't well supported by C++, consider using something like a factory pattern instead.

Basically you set up a hierarchy of classes that have virtual methods that implement what you're trying to do in the if cases. You then make a function that creates the appropriate child class from a set of strings, and then you call go or whatever on the created instance.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜