给定一个任意容器,推导出相关类型的容器类型

Ran*_*tep 4 c++ template-meta-programming type-alias

假设我有一个模板化类Wrapper,有没有办法创建一个类型别名模板,自动Wrapper <T>从 的容器推导出 的容器T,以便:

  • alias(Wrapper, vector<int>)会成为vector<Wrapper<int>>
  • alias(Wrapper, map<int, string>)会成为map<Wrapper<int>, Wrapper<string>>
  • alias(Wrapper, array<int, 10>)会成为array<Wrapper<int>, 10>

到目前为止,我最好的尝试是:

template<template<typename> typename U, template<typename...> typename Container, typename ...T>
using alias = std::remove_cvref_t<decltype(std::declval<Container<U<T>...>>())>;
Run Code Online (Sandbox Code Playgroud)

但有两个问题:

  1. 必须使用如下语法来调用它:这个版本需要被称为(这并不理想):alias(vector, Type)alias(map, Key, Value)alias(vector<Type>)如果可能的话,我很乐意使用alias(map<Key, Value>)

  2. 它不兼容,std::array因为 的第二个模板参数array不是size_t类型。我想我可以创建第二个类型别名并根据容器类型调用相应的别名,但我宁愿不必这样做。

Mar*_*k R 6

不确定这是否正是您所需要的,但是类模板的专业化可以很好地处理这个问题:

#include <type_traits>
#include <vector>
#include <array>
#include <map>
#include <string>

template<template<typename> typename Wrapper, typename Container>
struct repack;

template<template<typename> typename Wrapper, typename ValueT>
struct repack<Wrapper, std::vector<ValueT>>
{
    using type = std::vector<Wrapper<ValueT>>;
};

template<template<typename> typename Wrapper, typename ValueT, std::size_t N>
struct repack<Wrapper, std::array<ValueT, N>>
{
    using type = std::array<Wrapper<ValueT>, N>;
};

template<template<typename> typename Wrapper, typename Key, typename Value>
struct repack<Wrapper, std::map<Key, Value>>
{
    using type = std::map<Wrapper<Key>, Wrapper<Value>>;
};

template<template<typename> typename Wrapper, typename Container>
using repack_t = typename repack<Wrapper, Container>::type;
Run Code Online (Sandbox Code Playgroud)

https://godbolt.org/z/naz9v48vb

它通过了您指定的测试。