减少 if/if 代码量 (C++)

发布于 2024-10-13 17:03:15 字数 1245 浏览 2 评论 0原文

在我的程序中,我必须创建一个对象,如下所示:

Library::Param1::Param3 (不知道如何命名 Param,也许类型?) 类似于 std::vector::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; is not neseccary.

因此,我需要减少这些 if 语句的数量,但我不知道如何做到这一点。我认为可以使用模板来完成,但我对它们不熟悉,所以,我想,我需要一个代码示例。

抱歉英语不好,如果需要更多信息 - 请告诉我。谢谢。

--- 编辑:库(CryptoPP)类型定义:

由于错误仅出现在 Param1 上,因此发布它的一种变体:

//! 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;
};

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 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;
};

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

三岁铭 2024-10-20 17:03:15

我同意 Mark B 的观点,即工厂会很好,但我不确定如果您没有所有这些类型继承的基类,这是否可能。如果我正确理解了问题,则 Value 1 有 15 种类型,Value2 有 15 种类型,这会导致 15*15 个 if 语句。您可以使用以下方法将它们减少到 2*15:(未经测试)

---EDIT1:更改了方法的顺序 ---

模板
无效级别2()
{
类型名 T1_T2::Param3 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 执行的任何操作处理你的对象;如果没有基类,从 level0/1/2 返回 obj 将无法工作。

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.

杀手六號 2024-10-20 17:03:15

不要使用像这样的 if 语句动态更改类型(C++ 不太支持这种方式),而是考虑使用工厂模式之类的东西。

基本上,您设置了一个具有虚拟方法的类层次结构,这些虚拟方法实现了您在 if 情况下尝试执行的操作。然后,您创建一个函数,从一组字符串创建适当的子类,然后在创建的实例上调用 go 或其他任何内容。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文