我需要std::condition,但有两个以上的选择

I need std::conditional but with more than two choices

本文关键字:两个 选择 std condition      更新时间:2023-10-16

问题是,我有堆栈类模板,我想根据从文件中获取的数字或字符来决定创建哪种类型的对象。 所以而不是

if(T=='I')
{
myStack<int> teststack;
}
else if(T=='D')
{
myStack<double> teststack;
}

我想做一些允许我在"if"范围之外使用堆栈的事情

最接近的东西是 std::conditional,但在我的情况下,这应该像这样工作:

template<int type, class first, class second, class third>

所以我可以像这样使用它

int i;
input>>i;
myStack<i> teststack;

根据我拥有的数字,它应该是第一、第二或第三种类型。 我知道这不是最好的问题,但我只是有点困惑

获取i值(从流中(的方式意味着它的值只能在运行时知道。

这意味着std::conditional根本不适合您,因为条件表达式必须在编译时知道。

switch语句将得到您需要的东西,但大多数实现本质上C++简化为if语句链的switch

无论您想出什么解决方案,您都会有if语句。

有一个老生常谈的C++道理,即"首先正确实施,然后开始优化"。 因此,一连串if语句甚至switch语句的幼稚方法是完全可以接受的,甚至是最好的方法,直到你发现你需要更有效的方法。

但是,如果要消除将i与每个有意义的值进行比较的可能性,则可以使用类似std::map<char,some-callable-type>。在映射中查找i的值,并调用关联的可调用对象。

尝试类似操作:

#include<iostream>
#include<string>
#include<map>
#include<functional>
template<class T> struct myStack{};
template<class T> int doStuff()
{
myStack<T> mystack;
return 0;
}

int main()
{
char i;
std::map<char,std::function<int()>> doIt{
{'i', &doStuff<int>},
{'d', &doStuff<double>,},
{'l', []()->int{return 1;}},
{'s', &doStuff<std::string>}
};
std::cin>>i;
return doIt[i]();
}

(https://godbolt.org/z/fzhJc2(

如果可能性很少,您甚至可以使用std::array

std::conditionals 可以组合成一个开关:

using U = std::conditional_t<
T == 'I',
First, std::conditional_t<
T == 'D',
Second, Third>>;