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?
Here is my own attempt to do it without SFINAE:
template <typename F>
struct Algorithm {
void run() {
... // some computation here
myRun(std::integral_constant<
bool, std::is_same<decltype(F::f()), bool>::value>());
}
private:
void myRun(std::true_type) {
if (F::f()) return;
moreComputation();
}
void myRun(std::false_type) {
F::f();
moreComputation();
}
void moreComputation() { ... }
};
You should use SFINAE instead of branching at runtime.
You function run should look like this:
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
}
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With