代码之家  ›  专栏  ›  技术社区  ›  user6071088

在constexpr函数中切换

  •  9
  • user6071088  · 技术社区  · 7 年前

    Wiki

    C++11引入了constexpr声明函数的概念;一 可能会被需要常量表达式的操作消耗, 例如整数模板参数。然而,C++11 constexpr 以及static_断言和少量其他声明)。

    C++14放宽了这些限制。Constexpr声明的函数现在可以 包含以下内容:条件

    • 分支语句 if switch

    那么,在c++14/c++17中,在constexpr函数中真的有可能有一个开关吗?如果可能的话,它的语法是什么? 例如,我想要这样的东西:

    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;
            ...
        }
    }
    
    2 回复  |  直到 7 年前
        1
  •  24
  •   JesseC    5 年前

    不完全是这样。假使 if constexpr ,您可以放心,生成的代码没有分支。此外,丢弃的语句不需要编译。这些是我认为你会从一个真正的 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
    }
    

    顺便说一句,对于鲍姆公认的答案,我有点挑剔,这对于实用的瞳孔来说很好。我怀疑您会发现,好的编译器可以使用constexpr函数甚至非constexpr内联函数从switch case语句中删除逻辑上不可能的位。

        2
  •  18
  •   Baum mit Augen    7 年前

    那么,在c++14/c++17中,在constexpr函数中真的有可能有一个开关吗?

    如果可能的话,它的语法是什么?

    switch

    constexpr int fun (int i) {
        switch(i) {
            case 0: return 7;
            default: return 5;
        }
    }
    
    int main () {
        int arr[fun(3)];
    }