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.
精彩评论