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

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

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

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;

根据我的号码,它应该是第一类、第二类或第三类。 我知道这不是最好的问题,但我有点困惑

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

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

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

这意味着 std::conditional 对你根本不起作用,因为条件表达式必须在编译时知道[=48] =].

一个 switch 语句会得到你所需要的,但大多数 C++ 实现本质上是将 switch 简化为一串 if 语句。

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

有一个陈旧的 C++ 老生常谈 "implement correctly first, then start optimizing"。因此,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