首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在不重复代码的情况下使用if-constexpr?

如何在不重复代码的情况下使用if-constexpr?
EN

Stack Overflow用户
提问于 2017-10-13 03:37:23
回答 3查看 80关注 0票数 4

目前我正在做:

代码语言:javascript
复制
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(),然后在两个地方调用它,但是它似乎很难处理,因为我必须编写一个只为方便元编程而存在的函数。

我想要的是:

代码语言:javascript
复制
if not constexpr(constexpr_bool_var1 && some_magic(costly_runtime_function(arg1, arg2)) {
  // do X, do Y
} 

另一种方式是:

代码语言:javascript
复制
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条件之外声明的,因此它们将被不必要地实例化。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-10-13 14:21:39

我不确定我是否正确地理解了您的问题;您的原始代码和您的第二个选项没有表达完全相同的功能( costly_runtime_function的意思从“do X和Y”反转到“不要做X和Y”),在您的第一个恰当的选项中,我不理解您建议的语法或some_magic是什么。我用原始代码示例的语义回答您的问题。

处理这一问题的最佳方法可能是使用一个标志来确定是否执行X和Y操作:

代码语言:javascript
复制
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 . points out在注释中所述,编译器可能无论如何都可以处理优化。不过,这使人类读者更清楚地认识到,您希望在编译时处理这个问题。

票数 3
EN

Stack Overflow用户

发布于 2017-10-13 05:43:22

这里有一条路。它是否更有表现力/可维护性,我不能说。

代码语言:javascript
复制
#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();
}
票数 0
EN

Stack Overflow用户

发布于 2017-10-13 15:08:34

你可以用羔羊来做这个:

代码语言:javascript
复制
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作用域中传递不同类型的变量。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46722147

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档