最近发现的 C++ 笑话: switch(a){ case 1: return 1;}

6次阅读

共计 513 个字符,预计需要花费 2 分钟才能阅读完成。

想必大家都听说过「Java 程序员的吐槽」说低水平的同事写出这种代码:

if(status == A) {playwith(A);
}
if(status == B) {playwith(B);
}
//...

然后这种吐槽的下面还会有不少人煞有介事地分析,说可能是老代码删改留下的痕迹,以前没有一个统一的 playwith() 函数云云……

今天很高兴地通知大家,我们 c++, 即使是 新代码,也完全可能 会写出这种段落,而且这种段落完全 有意义! :)

Make sense 的关键在于,playwith()函数 不再一定能 在当前的函数上下文调用了。
c++20 引入的 consteval function 会阻止传入任何非 constexpr 的参数,所以你在一个运行时的 switch context 里是不能用运行期值去调用 consteval 函数的:

    // this lambda is conteval
    auto flatten = [](E _e) consteval {auto [id, extra] = static_map(_e);
        auto [name, info] = std::move(extra);
        return make_tuple(static_cast(_e), id, name, info);
    };
    cout << std::apply([](auto &&...args) {return std::format("in case {}, id {} (name:{}) has info: {}n",
                               args...);
        },
        // flatten(FOO));  // work, but only with literal
        to_runtime(flatten, e));  // work at runtime

那这个 to_runtime() 怎么写呢?
—— 没错,只能判断每个可能的编译期值了,于是我们得到了

switch(c){case 1: consteval_fn(1);}

在 compiler explorer 上查看这个例子
例子 on gist

p.s. consteval 函数编译起来是真的很慢,为了这样一个 编译期 map 代价还挺大的

正文完
 0