根据作为模板参数的函数的返回值避免分支

Alw*_*ing 6 c++ c++11

假设以下策略类负责算法的一个方面:

struct VoidF {
    static void f() {
        ... // some code that has side effects
    }
};

struct BoolF {
    static bool f() {
        bool res = ...; // some computation
        return res;
    }
};
Run Code Online (Sandbox Code Playgroud)

BoolF政策是"增强感知":当BoolF :: f()的返回true,该算法可以退出.VoidF是"增强 - 不知道",因此它返回void(我不想强迫我的库的用户返回,bool当它对他没有任何意义).

该算法目前编写如下:

template <typename F>
struct Algorithm {
    void run() {
        ... // some computation here

        if (std::is_same<decltype(F::f()), bool>::value) {
            if (F::f()) return;
        } else
            F::f(); // If F is VoidF, there should be no branching and some
                    // compiler optimizations will be enabled

        ... // more computation, unless F::f() got rid of it
    }
};
Run Code Online (Sandbox Code Playgroud)

当然,如果用Algorithm实例化,这不起作用VoidF.有没有办法解决这个问题,Algorithm<VoidF>::run()因为评论中指出不应该有分支?

Gui*_*cot 2

您应该使用 SFINAE 而不是在运行时分支。

你的函数 run 应该是这样的:

template <typename F>
struct Algorithm {

    void run() {
        ... // some computation here

        doRun();
    }

    template<std::enable_if_t<std::is_same<decltype(F::f()), bool>::value, int> = 0>
    void doRun() {
        if (F::f()) {
            // do some more computations if needed or simply remove the if and return
        }
    }

    template<std::enable_if_t<!std::is_same<decltype(F::f()), bool>::value, int> = 0>
    void doRun() {
        F::f();

        ... // more computation, unless F::f() got rid of it
    }
};
Run Code Online (Sandbox Code Playgroud)