可变参数模板上的变换算法

Transform algorithm on a variadic template

我正在使用 C++11,我需要像 transform(容器的 stl 算法)这样的东西,它可以将 template<typename ...T> 转换为 <typename ...T::something>,这样我就可以将它用于继承:

例如:

template<typename T>
struct typeOf{
   using type = T;
};

template<typename ...T> // All the arguments must be `typeOf`'s
class tupleOf : tuple<T::type...>{
}

这样 :

tupleOf<typeOf<int>,typeOf<char>> 会给我 tuple<int,char>

我想在不使用 C++14 功能的情况下执行此操作

您可以这样做:

template <typename T, template <typename> class f>
struct transform;


template <template <typename...> class C, typename...Ts, template <typename> class f>
struct transform<C<Ts...>, f>
{
    using type = C<typename f<Ts>::type...>;
};

和用法:

static_assert(std::is_same<std::tuple<char, int>,
                           transform<std::tuple<char*, int*>, 
                                     std::remove_pointer>::type>::value,
              "unexpected");

Live Demo.

如果您只是在寻找针对您的特定问题的简单解决方案,这应该适合您:

namespace detail {
    //primary template for when something invalid is passed
    //could add a static_assert to improve compiler message
    template<typename... T> struct tupleOf;

    //partial specialization for when a list of typeOf types are passed
    template<typename... Ts>
    struct tupleOf<typeOf<Ts>...>
    {
        using type = std::tuple<Ts...>;
    };
}

//alias template for ease-of-use
template <typename... Ts>
using tupleOf = typename detail::tupleOf<Ts...>::type;

现在 tupleOf<typeOf<int>,typeOf<char>> 等同于 std::tuple<int,char>.

简单的转换已经在模式扩展的上下文中起作用。如果您只添加 typename 关键字,您的原始代码应该可以正常工作。

template<typename T>
struct typeOf{
   using type = T;
};

template<typename ...T> // All the arguments must be `typeOf`s
class tupleOf : tuple<typename T::type...>{
};

尽管模板别名可能是更好的选择。

template <typename... T>
using tupleOf = tuple<typename T::type...>;