目前我在做:
if constexpr(constexpr_bool_var1) {
auto arg1 = costly_arg1(); auto arg2 = costly_arg2();
if (costly_runtime_function(arg1, arg2)) {
// do X, possibly more constexpr conditions
// do Y
// ...
}
} else {
// do X, possibly more constexpr conditions
// do Y
// ...
}
一种可能的方法是将do X / Y等转换为一个函数doXY()并在两个地方调用它,但是它看起来非常笨重,因为我必须编写一个仅为了方便元编程而存在的函数
我想要的是:
if not constexpr(constexpr_bool_var1 && some_magic(costly_runtime_function(arg1, arg2)) {
// do X, do Y
}
另一种方式是:
auto arg1 = costly_arg1(); // Unneeded extra work out not within constexpr
auto arg2 = costly_arg2();
if (constexpr_bool_var1 && costly_runtime_function(arg1, arg2)) {
} else {
// do X, possibly more constexpr conditions
// do Y
// ...
}
然而,这里arg1和arg2被声明在if条件之外,所以它们将被不必要地实例化。
答案 0 :(得分:3)
我不确定我是否理解你的问题;你的原始代码和你的第二个选择不表达完全相同的功能(costly_runtime_function
的含义从“执行X和Y”反转为“不做X和Y”),并在你的第一个提议中替代方案我不明白你提出的语法或some_magic
是什么。我正在用原始代码示例的语义回答你的问题。
处理此问题的最佳方法可能是标记是否执行X和Y:
bool do_x_y = true;
if constexpr(constexpr_bool_var1) {
// Maybe we don't actually want X and Y
auto arg1 = costly_arg1(); auto arg2 = costly_arg2();
do_x_y = costly_runtime_function(arg1, arg2);
}
if (do_x_y) {
// do X, possibly more constexpr conditions
// do Y
// ...
}
请注意,作为注释中的Andrei R. points out,编译器可能无论如何都可以处理优化。这使得您希望在编译时处理这个问题的人类读者更清楚。
答案 1 :(得分:0)
这是一种方式。它是否更具表现力/可维护性,我不能说。
#include <cstdlib>
#include <utility>
/*
* simulation
*/
void doX() {}
void doY() {}
int costly_arg1() { return 1; }
int costly_arg2() { return 2; }
bool costly_runtime_function(int, int) { return rand() < RAND_MAX / 2; }
constexpr bool constexpr_bool_var1 = true;
/*
* A functor that maybe does something
*/
template<class F>
struct maybe_do
{
constexpr maybe_do(F&& f) : f(std::move(f)) {}
constexpr void operator()() const
{
if (enabled)
f();
}
constexpr void enable(bool e) {
enabled = e;
}
F f;
bool enabled = true;
};
int main()
{
auto thing = maybe_do{
[] {
doX();
doY();
}
};
if constexpr(constexpr_bool_var1)
{
thing.enable(costly_runtime_function(costly_arg1(),
costly_arg2()));
}
thing();
}
答案 2 :(得分:0)
你可以使用lambda:
auto stuff = [&] {
// do X, possibly more constexpr conditions
// do Y
// ...
};
if constexpr(constexpr_bool_var1) {
auto arg1 = costly_arg1(); auto arg2 = costly_arg2();
if (costly_runtime_function(arg1, arg2)) {
stuff();
}
} else {
stuff();
}
如果你的lambda可以接收自动值,你也可以从if
范围内传递不同类型的变量。