An initializer_list holds elements of one type — so two different functors can only share a list through a common base pointer. That is type erasure in its rawest form: a virtual operator() behind a base class. std::function does the same job with more comfort; here you build the skeleton.
Make a range-for over {make_increment<int>(), make_twice<int>()} work: both factories return pointers to a COMMON base with a virtual operator(), so different operations live in one initializer_list and are applied through one call.
The initializer_list deduces ONE element type — make both factories return Op<T>*.
operator() can be virtual like any other member — override it in each derived operation.
Hit Submit (or ⌘/Ctrl + ↵) — test results will show up here.