Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 减少if/if代码的数量(C+;+;)_C++_Templates_If Statement - Fatal编程技术网

C++ 减少if/if代码的数量(C+;+;)

C++ 减少if/if代码的数量(C+;+;),c++,templates,if-statement,C++,Templates,If Statement,在我的程序中,我必须创建一个对象,如下所示: Library::Param1::Param3(不知道如何命名Param,可能是类型?) 类似于std::vector::iterator 因此,这些参数需要通过字符串进行更改。例如: if(param1 == "1_VALUE1") { if(param2 == "2_VALUE1") { MyLib::1_VALUE1<MyLib::2_VALUE1>::Param3 obj; //Ob

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

Library::Param1::Param3
(不知道如何命名
Param
,可能是类型?) 类似于
std::vector::iterator

因此,这些参数需要通过字符串进行更改。例如:

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)*/
<> >而不是使用<代码>动态更改类型>如果语句,这不是C++所支持的,请考虑使用类似工厂模式的东西。
基本上,您建立了一个类的层次结构,这些类具有虚拟方法,可以实现您在
if
情况下尝试执行的操作。然后,创建一个函数,从一组字符串创建适当的子类,然后在创建的实例上调用
go
或其他任何函数。

我同意Mark B的观点,工厂是不错的,但如果没有所有这些类型都从中继承的基类,我不确定这是否可行。如果我正确理解了这个问题,那么值1有15种类型,值2有15种类型,这导致了15*15 If语句。您可以使用以下方法将它们减少到2*15:(未测试)

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

模板 空二级() { 类型名T1_T2::Param3 obj; 剂量测定法(obj); }

模板
无效级别1(标准::字符串参数2)
{
如果(参数2==“2_值1”)
第2级();
如果(参数2==“2_值1”)
第2级();
...
}
无效级别0(标准::字符串参数1,标准::字符串参数2)
{
如果(参数1==“1_值1”)
一级(二级);
如果(参数2==“1_值2”)
一级(二级);
...
}
---编辑2---

为了帮助您找出无法编译的原因,可以从以下示例代码开始(在Visual Studio 2008上编译):

void doSomething(int x)
{
}
结构类型2_1{};
模板
结构类型1\u 1
{
typedef int参数3;
};
模板
结构类型1_2
{
typedef int参数3;
};
模板
无效级别1(标准::字符串参数2)
{
如果(参数2==“2_值1”)
第2级();
}
无效级别0(标准::字符串参数1,标准::字符串参数2)
{
如果(参数1==“1_值1”)
一级(二级);
如果(参数2==“1_值2”)
一级(二级);
}
模板
空二级()
{
类型名T1_T2::Param3 obj;
剂量测定法(obj);
}
int main(int argc,char*argv[])
{
0级(“1单位价值1”、“2单位价值1”);
返回0;
}

请注意,“doSomething()”应该是您希望MyLib对您的obj执行的任何操作;如果没有基类,从0/1/2级返回obj将无法工作。

如何使用这些对象?你对它们做了相同或相似的事情吗?它们的用法完全相同。所以它们都有一个方法(比方说它叫foo())?这是一个虚拟方法吗?所有这些类型都继承自同一个抽象基类吗?如果这些
在哪里,您能更具体地说明一下吗?这是一个函数吗?或者?我创建它们,并将它们作为参数传递到库函数中。您能举个例子吗?(链接到适当的示例)。正如我在评论中所说,“我创建它们,并将其作为参数传递到库函数中”。比如
MyLib::foo(obj)
在level0中,它会抱怨:
在“>”标记之前缺少模板参数
。能否重新生成level2函数,使其返回对象?(那么返回值是什么?如果需要,我应该创建什么变量来存储它?)。对不起,我指的是返回类型。两个想法:1。)您可能希望在级别1之前定义级别2,在级别0之前定义级别1。2)你们这类人的真名是什么?我希望不是1_ValueX?这是无效的。我不明白你的意思。也许,我甚至不需要创建一个变量来存储
obj
。我只需将返回值传递给库函数(请参阅我对Mark B answer的注释)。如果你问这个问题,所有可能的字符串值都会被if`s覆盖。@EdgeLuxe:没有实用的解决方案从
级别[0-2]
函数返回对象。函数创建15×15(225)不同的、不相关的对象类型,而C++中的函数只能返回单个类型的对象。code>Boost::Variant
Boost::Any
一开始可能看起来很有希望,但当您需要访问变量时,您会遇到“此处实际存储的是什么类型”的问题。
//! 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;
};
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);
 ...
}
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;
}