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



假设我有一个模板类Wrapper,有没有办法创建一个类型别名模板,自动从T的容器推断出Wrapper <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>...>>())>;

但是有两个问题:

  1. 必须用如下语法调用:这个版本需要被调用(这不是理想的):alias(vector, Type)alias(map, Key, Value)。如果可能的话,我想使用alias(vector<Type>)alias(map<Key, Value>)
  2. std::array不兼容,因为array的第二个模板参数是size_t而不是类型。我想我可以创建第二个类型别名,并根据容器类型调用相应的别名,但我希望不必这样做。

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

#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;

https://godbolt.org/z/naz9v48vb

通过您指定的测试。

目前没有办法将non-type-template-parameters与type-template-parameter或template-template-parameter混合使用。

然后对于限制为type-template-parameter的alias,您可以这样做:

template <template <typename> class Inner, typename Container>
struct alias;
template <template <typename> class Inner,
template <typename...> class C,
typename... Ts>
struct alias<Inner, C<Ts...>>
{
using type = C<Inner<Ts>...>;
};
template <template <typename> class Inner, typename Container>
using alias_t = typename alias<Inner, Container>::type;

的用法是

alias_t<Wrapper, vector<int>>而非alias(Wrapper, vector<int>).

但是正如在注释中提到的,通用方式将包装所有参数,包括默认参数(如Allocator)。

选择Marek R所展示的专门化可能更合适。

相关内容

  • 没有找到相关文章

最新更新