【问题标题】:Switch in constexpr function切换 constexpr 函数
【发布时间】:2018-01-14 00:31:39
【问题描述】:

Wiki找到如下语句:

C++11 引入了 constexpr 声明函数的概念;一种 可以在编译时执行的函数。他们的返回值 可以被需要常量表达式的操作使用, 例如整数模板参数。但是,C++11 constexpr 函数只能包含一个返回的表达式(如 以及 static_asserts 和少量其他声明)。

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

  • ...
  • 分支语句ifswitch

那么,在 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;
        ...
    }
}

【问题讨论】:

  • 你试过编译吗?
  • 我的意思是,这行得通:ideone.com/pjMrvr
  • @Carcigenicate,呃,哦。原来这只是我的旧 g++ (4.9.2) 中的一个错误。但它适用于 clang 3.5
  • 我从整个页面中什么也没学到。
  • 这里的实际答案:stackoverflow.com/a/53379817/1599699

标签: c++ c++14 constexpr c++17


【解决方案1】:

不完全是。对于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
}

顺便说一句,我对 Baum 接受的答案有点挑剔,这对于实际目的来说很好。我怀疑你会发现好的编译器会从带有 constexpr 函数的 switch-case 语句中删除逻辑上不可能的位,甚至是非 constexpr 内联函数。

【讨论】:

    【解决方案2】:

    那么,在 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)];
    }
    

    【讨论】:

    • 并不是说静态开关(就像静态循环一样)不会很好。库解决方案有一些明显的缺点。
    猜你喜欢
    • 1970-01-01
    • 2021-04-20
    • 1970-01-01
    • 1970-01-01
    • 2015-05-22
    • 2020-12-13
    • 1970-01-01
    • 2018-07-10
    • 2020-10-08
    相关资源
    最近更新 更多