Suppose the following policy classes that take care of one aspect of an algorithm:
struct VoidF {
    static void f() {
        ... // some code that has side effects
    }
};
struct BoolF {
    static bool f() {
        bool res = ...; // some computation
        return res;
    }
};
The BoolF policy is "enhancement-aware": when BoolF::f() returns true, the algorithm can exit. VoidF is "enhancement-unaware", hence it returns void (I don't want to force the user of my library to return bool when it does not mean anything to him).
The algorithm is currently written like this:
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
    }
};
Of course, this does not work if Algorithm is instantiated with VoidF. Is there a way to fix this in a way that there should be no branching in Algorithm<VoidF>::run() as indicated by the comment?