I'm currently playing around with template metaprogramming. I'm trying to make a finite state machine by using tmp. I know that there are several implementations in the web but I want to implement one by myself as an exercise.
I have a class called Condition
which is the base class for the condition of a transition between two states. One implementation is the AnyCondition
class:
template<class Input, Input comp, Input ... comps >
class AnyCondition: public Condition<Input>
{
public:
AnyCondition() {}
bool operator()(const Input& input) const override
{
return input == comp || AnyCondition<Input, comps...>()(input);
}
};
The thing here is, that the compiler will expand this recursivly, which results in a lot of recursive calls at runtime due to the input
parameter. It should be more efficent, if the expanded code would be a statement like:
bool operator()(const Input& input) const override
{
return input == comp1 || input == comp2 || input == comp3...
}
Is this possible somehow?
C++17 solution - fold expression:
template <typename... Ts>
auto anyCondition(Ts... xs)
{
return (xs || ...);
}
wandbox example
C++11 solution - for_each_argument
:
template <typename TF, typename... Ts>
void for_each_argument(TF&& f, Ts&&... xs)
{
(void)(int[]){(f(std::forward<Ts>(xs)), 0)...};
}
template <typename... Ts>
auto anyCondition(Ts... xs)
{
bool acc = false;
for_each_argument([&acc](bool x){ acc = acc || x; }, xs...);
return acc;
}
wandbox example
I gave a talk about this snippet at CppCon 2015:
CppCon 2015: Vittorio Romeo “for_each_argument
explained and expanded"
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