I have:
struct spacer : foo<bar>{};
struct sequence : baz<qux, spacer, quz, spacer, plugh>{};
I would like to be able to write (something like this, exact syntax doesn't matter):
struct spaced_sequence : SPACED_BAZ<qux, quz, plugh>{};
Can this be done with macros/templates/anything else?
CodePudding user response:
You can do the following:
Create a base case function template that appends a single type T to some specialization of baz
template<typename T, typename ... Args>
auto append(baz<Args...>) -> baz<Args..., T>;
Note that no spacer is added here, since T is the last type we're adding.
Then write a recursive case, also as a function template, that gets called if there are at least 2 more types T1, and T2 that need to be added
template<typename T1, typename T2, typename ...Rest, typename ... Args>
auto append(baz<Args...>)
-> decltype(append<T2, Rest...>(std::declval<baz<Args..., T1, spacer>>()));
// insert spacer after T1 ^
// ^ pass the remaining types recursively
and finally add a convenience alias
template<typename ...Ts>
using SPACED_BAZ = decltype(append<Ts...>(std::declval<baz<>>()));
// types to add ^ and baz is empty to start
Here's a demo.
CodePudding user response:
You can do something like this (assuming know number of arguments):
template <class T1, class T2, class T3>
using SPACED_BAZ = baz<T1, spacer, T2, spacer, T3>;
If you have more type, you can do other alias as required.
