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

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

Library::Param1<Library::Param2>::Param3 (I don’t know what to call Param , perhaps types?) Similar to std::vector<std::string>::iterator .

So these Param need to be changed line by line. For instance:

 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; not unclassified.

So, I need to reduce the number of these if statements, but I don't know how to do this. I think this can be done using templates, but I am not familiar with them, so I think I will need a sample code.

Sorry for poor English, if you need more information - let me know. Thanks.

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

Since errors refer only to Param1, exposing one of them:

 //! 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; }; 
+4
source share
2 answers

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

--- EDIT1: reordered methods ---

template void level2 () {typename T1_T2 :: Param3 obj; FUNCTIONAL (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 understand why you cannot compile, you can start with this sample code (compiled in 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; } 

Note that "doSomething ()" should be whatever you want MyLib to do with your obj; Returning obj from level0 / 1/2 will not work without a base class.

+3
source

Instead of dynamically changing the type using if statements that are not supported by C ++, consider something like a factory pattern instead.

Basically, you set up a hierarchy of classes that have virtual methods that implement what you are trying to do in if cases. Then you create a function that creates the corresponding child class from the rowset, and then you call go or something else in the instantiated instance.

0
source

Source: https://habr.com/ru/post/1336601/


All Articles