如何提取没有模板参数的对象的类模板?

问题描述 投票:0回答:2

如何提取对象的模板来声明具有不同模板参数的新对象?

如果可能的话,我正在寻找具有以下用法的东西:

#include <vector>

int main() 
{
  std::vector<float> a;
  std::array<int, 7> b;

  get_template<decltype(a), unsigned> new_a; // std::vector<unsigned>
  get_template<decltype(b), float, 85> new_b; // std::array<float, 85>

  return 0;
}
c++ templates template-meta-programming decltype class-template
2个回答
3
投票

如何提取对象的模板来声明具有不同模板参数的新对象?

如果可能的话[...]

是的,您可以执行以下操作:

// Primary template
template<typename T> struct get_template;

// Specialization for std::vector
template<typename T, typename Allocator>
struct get_template<std::vector<T, Allocator>> {
   template<typename U, typename UAllocator = std::allocator<U>>
   using type = std::vector<U, UAllocator>;
};

// Specialization for std::array
template<typename T, std::size_t N>
struct get_template<std::array<T, N>> {
   template<typename U, std::size_t UN = N>
   using type = std::array<U, UN>;
};

// ... so on for other containers!

// Helper alias for both specializations
template<typename Container, typename U, auto... Ts>
using get_template_t = typename get_template<Container>::template type<U, Ts...>;

你会这样使用它:

std::vector<float> a;
std::array<int, 7> b;

get_template_t<decltype(a), unsigned> new_a; // std::vector<unsigned>
get_template_t<decltype(b), float, 85> new_b; // std::array<float, 85>

观看现场演示


1
投票

您可以专门针对类型和非类型参数的特定组合,但您无法拥有完全通用的解决方案。

// Primary template
template<typename T> struct get_template;

// Specialization for types with no non-type parameters
template<template<typename...> typename Container, typename... Ts>
struct get_template<Container<Ts...>> {
   template<typename... Us>
   using type = Container<Us...>;
};

// Specialization for types with a type parameter followed by non-type parameters
template<template<typename, auto...> typename Container, typename T, auto... Ns>
struct get_template<Container<T, Ns...>> {
   template<typename U, auto... UNs>
   using type = Container<U, UNs...>;
};

template<typename Container, typename... Us>
using get_template_t = typename get_template<Container>::template type<Us...>;

template<typename Container, typename T, auto... Us>
using get_template_value_t = typename get_template<Container>::template type<T, Us...>;

std::vector<float> a;
std::array<int, 7> b;

static_assert(std::same_as<get_template_t<decltype(a), unsigned>, std::vector<unsigned>>);
static_assert(std::same_as<get_template_value_t<decltype(b), float, 85>, std::array<float, 85>>);
© www.soinside.com 2019 - 2024. All rights reserved.