Switch in constexpr function

血红的双手。 提交于 2020-01-13 12:16:12

问题


Found the following statement in Wiki:

C++11 introduced the concept of a constexpr-declared function; a function which could be executed at compile time. Their return values could be consumed by operations that require constant expressions, such as an integer template argument. However, C++11 constexpr functions could only contain a single expression that is returned (as well as static_asserts and a small number of other declarations).

C++14 relaxes these restrictions. Constexpr-declared functions may now contain the following: The conditional

  • ...
  • branching statements if and switch

So, Is it actually possible to have a switch in a constexpr function in c++14/c++17? And, if possible, what syntax is for that? For example, I'd like to have something like this:

enum class Terrain : std::uintmax_t {
    ROAD,
    SOIL,
    GRASS,
    MUD,
    SNOW,
};

constexpr float
getStepPrice(Terrain const& terrain)
{
    switch constexpr (terrain)
    {
        case Terrain::ROAD: return 1.0f;
        ...
    }
}

回答1:


So, Is it actually possible to have a switch in a constexpr function in c++14/c++17?

Yes.

And, if possible, what syntax is for that?

There is absolutely nothing special about the syntax, it's just a normal switch. Like this:

constexpr int fun (int i) {
    switch(i) {
        case 0: return 7;
        default: return 5;
    }
}

int main () {
    int arr[fun(3)];
}



回答2:


Not exactly. In the case of if constexpr, you can rest assured that the resulting code has no branching. Moreover, discarded statements need not compile. Those are the guarantees I think you would expect from a true switch constexpr.

class Dog;
class Snake;

#define USE_IF

template<typename Pet>
constexpr void foo(Pet pet) {
#ifdef USE_IF
    // This works
    if constexpr(std::is_same_v<Pet, Dog>)   pet.bark();
    else                                     pet.slither();
#else
    // This doesn't
    switch (std::is_same_v<Pet, Dog>) {
        case true:  pet.bark();    break;  // <== Error if Snake
        case false: pet.slither(); break;  // <== Error if Dog
    }
#else
}

BTW, I'm being a little nit-picky vis-a-vis Baum's accepted answer, which is fine, for practical puposes. I suspect you'd find good compilers will elide logically impossible bits from a switch-case statement with constexpr functions, as well as even non-constexpr inlined functions.



来源:https://stackoverflow.com/questions/45534410/switch-in-constexpr-function

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