Using strings in switch statements - where do we stand with C++17?

einpoklum picture einpoklum · Dec 27, 2016 · Viewed 8.3k times · Source

Every one of us has (probably) had the childhood dream of writing:

switch(my_std_string) {
case "foo":  do_stuff(); break;
case "bar":  do_other_stuff(); break;
default:     just_give_up();
}

but this is not possible, as is explained in the answers to this question from the olden days (2009):

Why switch statement cannot be applied on strings?

Since then we've seen the advent of C++11, which lets us go as far as:

switch (my_hash::hash(my_std_string)) {
case "foo"_hash:  do_stuff(); break;
case "bar"_hash:  do_other_stuff(); break;
default:          just_give_up();
}

as described in an answer to Compile time string hashing - which is not so bad, although it doesn't actually do exactly what we wanted - there's a chance of collision.

My question is: Has the development of the language since then (mostly C++14 I suppose) affected the way one would write a sort-of-a string case statement? Or simplified the nuts-and-bolts for achieving the above?

Specifically, with the conclusion of the C++17 standard being just around the corner - I'm interested in the answer given what we can assume the standard will contain.

Note: This is not a discussion on the merit of using switch statements, nor a thread on meta. I'm asking an informative question, so please answer/up/downvote based on that.

Answer

Yakk - Adam Nevraumont picture Yakk - Adam Nevraumont · Dec 27, 2016

It would be easy-ish to write

switcher(expr)->*
caser(case0)->*[&]{
}->*
caser(case1)->*[&]{
};

to build a statically sized hash table of case0 through caseN, populate it dynamically, test for collisions with ==, do the lookup via expr, and run the corresponding lambda.

Even caser(case3)->*caser(case4)->*lambda and ->*fallthrough could be supported.

I do not see a compelling need.

I see no advantage to writing this in C++17 either.