检索模板是从中实例化的

Retrieve the template a type is instantiated from

本文关键字:实例化 检索      更新时间:2023-10-16

如何检索模板最初是从?

实例化的?

我想做以下操作:

struct Baz{};
struct Bar{};
template <typename T>
struct Foo {};
using SomeType = Foo<Bar>;
template <typename T>
using Template = get_template<SomeType>::template type<T>;
static_assert(std::is_same<Foo<Baz>, Template<Baz>>::value, "");

我知道我可以通过部分专业化来实现这一目标,但是这迫使我专门为要使用它使用的每个模板专业化get_template

template <typename T>
struct get_template;
template <typename T>
struct get_template<Foo<T>>
{
    template <typename X>
    using type = Foo<X>;
};

实时示例

是否有解决此限制的方法?

您可以使用模板模板参数(应适用于任何数量的 type 参数):

template <typename T>
  struct get_template;
template <template <class...> class Y, typename... Args>
  struct get_template<Y<Args...>> {
    template <typename... Others>
    using type = Y<Others...>;
  };

然后获取模板:

template <typename T>
using Template = typename get_template<SomeType>::type<T>;

@yakk在评论中提到,以上仅适用于仅具有类型参数的模板。您可以专业地使用类型和非类型参数的特定模式的模板,例如:

// Note: You need the first size_t to avoid ambiguity with the first specialization
template <template <class, size_t, size_t...> class Y, typename A, size_t... Sizes>
  struct get_template<Y<A, Sizes...>> {
    template <class U, size_t... OSizes>
    using type = Y<U, OSizes...>;
  };

...但是您将无法将其专业用于任意模板。


演示(使用Foostd::pair):

#include <type_traits>
#include <map>
struct Bar{};
template <typename T>
struct Foo {};
using SomeType = Foo<Bar>;
template <typename T>
  struct get_template;
template <template <class...> class Y, typename... Args>
  struct get_template<Y<Args...>> {
    template <typename... Others>
    using type = Y<Others...>;
  };
template <typename T>
using Template = typename get_template<SomeType>::type<T>;
static_assert(std::is_same<SomeType, Template<Bar>>::value, "");
static_assert(std::is_same<Foo<int>, Template<int>>::value, "");
using PairIntInt = std::pair<int, int>;
using PairIntDouble = std::pair<int, double>;
template <typename U1, typename U2>
using HopeItIsPair = 
  typename get_template<PairIntDouble>::type<U1, U2>;
static_assert(std::is_same<PairIntDouble, HopeItIsPair<int, double>>::value, "");
static_assert(std::is_same<PairIntInt, HopeItIsPair<int, int>>::value, "");

不确定我有问题。这可以工作吗?

#include<type_traits>
#include<utility>
template<typename V, template<typename> class T, typename U>
auto get_template(T<U>) { return T<V>{}; }
struct Baz{};
struct Bar{};
template <typename T>
struct Foo {};
using SomeType = Foo<Bar>;
template <typename T>
using Template = decltype(get_template<T>(SomeType{}));
int main() {
    static_assert(std::is_same<Foo<Baz>, Template<Baz>>::value, "");
}

您可以更多地概括( SomeType可能是Template的模板参数),但它给出了一个方法。