如何检索实例化模板对象的类型?
How can I retrieve the type a templated object was instantiated with?
问题:
我想获取模板化类型实例化时使用的类型。例如std::shared_ptr<int>
我想得到 int
。下面的方法适用于这个简单的案例。不过,我需要实例化该类型的对象。这在某些情况下不起作用,例如std::shared_ptr<some_abstract_class>
或者如果默认构造函数被删除。
如果我们能够将抽象类型转换为具体类型,那么检索抽象类型仍然有用。
问题:
如何以无需实例化任何对象的方式更改下面的代码?
后续问题:
是否可以在不必将对象传递给此函数的情况下执行此操作?现在我正在将类型 outer<inner>
的对象传递给 get_inner_t
。我想避免这种情况并仅在模板元编程的帮助下检索 inner
。
我的做法:Live example.
template <typename inner, template <typename a> typename outer>
inner get_inner_t(outer<inner> nested_t) {
(void)nested_t;
typedef typename std::remove_cv_t<std::remove_reference_t<inner>> without_const_cv_innter_t;
without_const_cv_innter_t i;
return i;
}
int main() {
auto sp = std::make_shared<int>();
typedef decltype(get_inner_t(sp)) inner_t;
inner_t t = 5;
std::cout << t;
}
是的,这是可能的。只需使用模板 class (此处为结构)而不是模板函数。并使用 decltype
检索对象的类型并将其传递给模板 class.
以下是一种方法:
#include <memory>
#include <type_traits>
template<typename>
struct inner;
template<template<typename>class outter_t, typename inner_t>
struct inner<outter_t<inner_t> >{
typedef typename std::remove_cv<typename std::remove_reference<inner_t>::type>::type type;
};
template<typename _t>
using inner_t = typename inner<_t>::type;
int main()
{
auto sp = std::make_shared<int>();
typedef inner_t<decltype(sp)> inner_tt;
inner_tt t = 5;
std::cout << t;
}
这样您就不需要传递对象本身,而只需传递它的类型。我想这也适用于抽象类型。
问题:
我想获取模板化类型实例化时使用的类型。例如std::shared_ptr<int>
我想得到 int
。下面的方法适用于这个简单的案例。不过,我需要实例化该类型的对象。这在某些情况下不起作用,例如std::shared_ptr<some_abstract_class>
或者如果默认构造函数被删除。
如果我们能够将抽象类型转换为具体类型,那么检索抽象类型仍然有用。
问题:
如何以无需实例化任何对象的方式更改下面的代码?
后续问题:
是否可以在不必将对象传递给此函数的情况下执行此操作?现在我正在将类型 outer<inner>
的对象传递给 get_inner_t
。我想避免这种情况并仅在模板元编程的帮助下检索 inner
。
我的做法:Live example.
template <typename inner, template <typename a> typename outer>
inner get_inner_t(outer<inner> nested_t) {
(void)nested_t;
typedef typename std::remove_cv_t<std::remove_reference_t<inner>> without_const_cv_innter_t;
without_const_cv_innter_t i;
return i;
}
int main() {
auto sp = std::make_shared<int>();
typedef decltype(get_inner_t(sp)) inner_t;
inner_t t = 5;
std::cout << t;
}
是的,这是可能的。只需使用模板 class (此处为结构)而不是模板函数。并使用 decltype
检索对象的类型并将其传递给模板 class.
以下是一种方法:
#include <memory>
#include <type_traits>
template<typename>
struct inner;
template<template<typename>class outter_t, typename inner_t>
struct inner<outter_t<inner_t> >{
typedef typename std::remove_cv<typename std::remove_reference<inner_t>::type>::type type;
};
template<typename _t>
using inner_t = typename inner<_t>::type;
int main()
{
auto sp = std::make_shared<int>();
typedef inner_t<decltype(sp)> inner_tt;
inner_tt t = 5;
std::cout << t;
}
这样您就不需要传递对象本身,而只需传递它的类型。我想这也适用于抽象类型。