如何检索实例化模板对象的类型?

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

这样您就不需要传递对象本身,而只需传递它的类型。我想这也适用于抽象类型。