这里有一个返回类型的 C++11 解决方案,这样auto 就不需要使用了:
#include <iostream>
#include <type_traits>
#include <utility>
#include <string>
#include <tuple>
template <typename T, typename Map> struct FindCounterpartType;
template <typename T, template <typename...> class M, template <typename, typename> class P, typename U, typename... Pairs>
struct FindCounterpartType<T, M<P<T,U>, Pairs...>> {
using type = U;
};
template <typename T, template <typename...> class M, typename Pair, typename... Pairs>
struct FindCounterpartType<T, M<Pair, Pairs...>> : FindCounterpartType<T, M<Pairs...>> {};
template <typename Pack, typename Map, typename Output> struct ChangeTypesHelper;
template <template <typename...> class P, typename... Output, typename Map>
struct ChangeTypesHelper<P<>, std::tuple<Output...>, Map> {
using type = P<Output...>;
};
template <template <typename...> class P, typename First, typename... Rest, typename... Output, typename Map>
struct ChangeTypesHelper<P<First, Rest...>, std::tuple<Output...>, Map> : ChangeTypesHelper<P<Rest...>, std::tuple<Output..., typename FindCounterpartType<First, Map>::type>, Map> {};
template <typename Pack, typename Map>
struct ChangeTypes : ChangeTypesHelper<Pack, std::tuple<>, Map> {};
// Testing
template <typename...> struct M;
template <typename...> struct Pack;
template <typename, typename> struct P;
using Map = M< P<int, std::string>, P<char, std::size_t>, P<double, bool> >;
int main() {
std::cout << std::boolalpha << std::is_same<
ChangeTypes<std::tuple<int, char, double>, Map>::type,
std::tuple<std::string, std::size_t, bool>
>::value << '\n';
std::cout << std::is_same<
ChangeTypes<Pack<char, double, double, int, int, int, char>, Map>::type,
Pack<std::size_t, bool, bool, std::string, std::string, std::string, std::size_t>
>::value << '\n';
std::cin.get();
}