问题
I have a template function that accepts variadic arguments.
template<typename... Params>
void foo(Params... p);
I want to find all occurences of a given type (const char*
) in Params
to replace them with another type, that these values can be cast to (my own Path
class with constructor Path(const char*)
). The idea is to have something like
template<typename... Params>
void foo(Params... p) {
bar<convertCharPointerToPath<Params>...>(p...);
}
How can this conversion be done?
回答1:
If you want to convert types only, it's just a meta-function away:
template<typename T> struct convert {
using type = T;
};
template<> struct convert<char const*> {
using type = Path;
};
template<typename T>
using convertCharPointerToPath = typename convert<T>::type;
Now use it in your parameter pack expansion, as you do in your original post.
回答2:
Without a traits helper:
template<typename... Params>
void foo(Params... p) {
bar<std::conditional_t<std::is_same<char const*,Params>{},Path,Params>...>(p...);
}
or, with overload<Fs...>
:
auto identity=[](auto&&x)->decltype(x){return decltype(x)(x);};
template<typename... Params>
void foo(Params... p) {
auto convert = overload([](const char* p){return Path(p);},identity);
bar(convert(p)...);
}
overload
can be found everywhere; it takes a set of lambdas and returns their overload set.
Live example.
来源:https://stackoverflow.com/questions/48131712/cast-specific-types-in-variadic-argument