共计 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);}
p.s. consteval 函数编译起来是真的很慢,为了这样一个 编译期 map 代价还挺大的
正文完