Reputation: 955
I have a function f(int x, float y, char* z, .., bool b)
. The argument b
is used only in the fashion of:
if (b) {
...
} else {
...
}
in various parts of the function body. For efficiency reason, I would like to effectively create two functions f0
and f1
, where b
is set to false
and true
respectively, to avoid evaluating the conditional at run time. At the same time since the implementation of f
is fairly long, I don't want to explicitly define f0
and f1
separately. Is there any compiler optimization feature that automatically spawns these two branch functions at compile time?
Maybe there are better design patterns that avoid this line of thinking completely? Keep in mind that the conditional b
can be evaluated in a massive loop.
Upvotes: 1
Views: 246
Reputation: 217810
Template allows to factorize this kind of code, and C++17 allows it cleanly with if constexpr
:
template<bool b>
void f(int x, float y, char *z)
{
// ...
if constexpr (b)
{
// ...
}
else
{
// ...
}
// ...
}
// if you still need runtime dispatch
void f(int x, float y, char *z, bool b)
{
return b ? f<true>(x, y, z) : f<false>(x, y, z);
}
Without if constexpr
, it is not guaranty that there are no branch at runtime, but compiler might easily do it normally.
So if you want that guaranty pre-C++17, you have to specialize divergent part
by specialization:
template <bool b> void f_impl(..);
template <> void f_impl<true>(..) { /*..*/ }
template <> void f_impl<false>(..) { /*..*/ }
template<bool b>
void f(int x, float y, char *z)
{
// ...
f_impl<b>(..);
// ...
}
or tag dispatching:
void f_impl(std::true_type, ..) { /*..*/ }
void f_impl(std::false_type, ..) { /*..*/ }
template<bool b>
void f(int x, float y, char *z)
{
// ...
f_impl(std::integral_constant<bool, b>{}..); // std::bool_constant<b> in C++17
// ...
}
Upvotes: 3
Reputation: 6125
Use a template:
template<bool b>
void f(int x, float y, char *z)
{
if (b)
{
...
}
else
{
...
}
}
...
if (runtimeCondition)
{
f<true>(1, 2, "");
}
else
{
f<false>(1, 2, "");
}
Upvotes: 2