Reputation: 1526
Here, I want to rewrite a variadic template parameter pack and replace occurrence of some type with another. Here is a pseudocode-like example:
#include <string>
template <typename Params, typename Args>
struct TermRewrite {
template <typename... Body>
static auto constexpr eval(){
// Fill here...
}
};
int main() {
TermRewrite<int, char>::eval<int, std::string, double>();
// should give me pack of types as <char, std::string, double>
// ie. it should replace type int with char in Body...
}
So that I can chain these term rewrites in the end. Basically, I want to transform the variadic template before forwarding it. How can I achieve this? I am not able to come-up with a solution. For all you want to know, this is a made-up exercise for myself. Also, do you have any suggestions on usability so that it is easier to chain TermRewrite
calls?
Upvotes: 1
Views: 582
Reputation: 21160
You use parameter pack expansion with a metafunction taking a single argument
template<typename From, typename To>
struct replace
{
template<typename T>
using replace_fn = std::conditional_t<std::is_same_v<From, T>, To, T>;
template<typename... Args>
using apply = std::tuple<replace_fn<Args>...>;
};
Note you have to save the result as a template taking parameter packs like std::tuple
.
If you want to chain the replacement, you could write
template<typename From, typename To, typename... Args>
struct replace_impl
{
template<typename T>
using replace_fn = std::conditional_t<std::is_same_v<From, T>, To, T>;
using type = std::tuple<replace_fn<Args>...>;
};
template<typename From, typename To, typename... Args>
struct replace_impl<From, To, std::tuple<Args...>>
{
template<typename T>
using replace_fn = std::conditional_t<std::is_same_v<From, T>, To, T>;
using type = std::tuple<replace_fn<Args>...>;
};
template<typename From, typename To>
struct replace
{
template<typename... Args>
using apply = typename replace_impl<From, To, Args...>::type;
};
And use as
replace<char, float>::apply<replace<int, char>::apply<int, char, bool>>
But be careful that this means you are treating a single std::tuple
not as a type, but a list of types.
Upvotes: 4