如何提取对象的模板来声明具有不同模板参数的新对象?
如果可能的话,我正在寻找具有以下用法的东西:
#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;
}
如何提取对象的模板来声明具有不同模板参数的新对象?
如果可能的话[...]
是的,您可以执行以下操作:
// 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>
您可以专门针对类型和非类型参数的特定组合,但您无法拥有完全通用的解决方案。
// 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>>);