If there's an if-constexpr, how come there's no switch-constexpr?

时光怂恿深爱的人放手 提交于 2021-02-18 11:17:04

问题


In C++17, if constexpr was introduced; however, there doesn't seem to be a switch constexpr (see here). Why is that? That is, if a compiler supports if constexpr, is it not also trivial for it to support switch constexpr (at worst as an if-then-else-if-etc. chain, or multiple if's with some flags to control fallthrough)?


回答1:


if constexpr was ultimately derived from a more sane form of the static if concept. Because of that derivation, applying the same idea to switch does not appear to have been considered by the standards committee. So this is likely the primary reason: nobody added it to the paper since it was a restricted form of a syntax where switch wouldn't have made sense.

That being said, switch has a lot of baggage in it. The most notable bit being the automatic fallthrough behavior. That makes defining its behavior a bit problematic.

See, one of the powers of if constexpr is to make the side not taken at compile time be discarded under certain conditions. This is an important part of the syntax. So a hypothetical switch constexpr would be expected to have similar powers.

That's a lot harder to do with fallthrough, since the case blocks are not as fundamentally distinct as the two blocks of an if statement. Especially if you have conditional fallthrough. Now, you could make switch constexpr not have automatic fallthrough (or fallthrough at all), so that the different sections are distinct. But then you've subtly changed how the syntax works; a non-constexpr form of switch behaves differently from the constexpr form. That's not good.

Yes, you could make it a compile error to not put break; statements between the labels.

Note that the two main pattern-matching proposals, P1308 and P1260, specifically avoid using switch, instead inventing a new keyword. They both have constexpr aspects to them, but they make it abundantly clear that they are not switch/case.




回答2:


I am not authoritative, but if you look at the selection statements if has a clear separation between true and false statements, switch doesn't.

I presume it would be relatively harder to discard unused parts of switch from evaluation, especially since they can fall-through.

Reimplementing switch as if-else-if is not so straight forward if you want to maintain all the (exotic) capabilities of it.




回答3:


Consider the following example from the answer to another question (about optimized if branches).

struct Cat { void meow() { } };
struct Dog { void bark() { } };

template <typename T>
void pet(T x)
{
    if(std::is_same<T, Cat>{}){ x.meow(); }
    else if(std::is_same<T, Dog>{}){ x.bark(); }
}

pet(Cat{});
pet(Dog{});

You cannot replicate this with a switch because you would need the case values to actually be types; something like the following, which is impossible for obvious reasons.

template <typename T>
void pet(T x)
{
    switch (T) {
    case Cat:
        x.meow();
        break;
    case Dog:
        x.meow();
        break;
    }
}

This example is kind of the reason for if constexpr: comparing types or other things that aren't simply a set of values. So a switch constexpr does not make much sense to me. If anything, it would need another syntax (kind of like my example), and I'm not sure that it would be beneficial. It certainly isn't necessary.



来源:https://stackoverflow.com/questions/53379143/if-theres-an-if-constexpr-how-come-theres-no-switch-constexpr

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!