简体   繁体   中英

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

Thing is, I have stack class template, and I want to decide which type of object I create based on, say, number, or char I get from file. So instead of

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

i wanna do something which allows me to use stack out of "if" scope

closest thing was std::conditional, but in my case that should work something like that:

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

so I could use it like

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

And it should be first, second or third type based on number I have. I know thats not best question, but I just kinda confused a lot

The way you are acquiring the value of i (from a stream) means that its value can only be known at run time.

This means that std::conditional will not work at all for you, since the conditional expression has to be known at compile time .

A switch statement will get you what you need, but most implementations C++ essentially reduce a switch to a chain of if statements.

You will have if statements in whatever solution you come up with.

There is a well-worn C++ truism of "implement correctly first, then start optimizing". So the naïve approach of a chain of if statements or even a switch statement is a perfectly acceptable way of doing this, and even the best way , until you discover you need something more efficient.

However, if you want to eliminate the possibility of comparing i to every meaningful value, you can use something like a std::map<char, some-callable-type > . Look up the value of i in the map, and call the associated callable.

Try something like:

#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 )

You could even use a std::array if the number of possibilities is small.

std::conditional s can be combined to form a switch:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM