简体   繁体   中英

How can I retrieve the type a templated object was instantiated with?

Problem:

I would like to get the type a templated type was instantiated with. E. g.for std::shared_ptr<int> I want to get int . The approach below works for this simple case. I need to instantiate an object of that type, though. This does not work in some cases, eg std::shared_ptr<some_abstract_class> or if the default constructor is deleted.

Retrieving an abstract type can still be useful if we are able to cast it to a concrete type.

Question:

How can I change the code below in a way that there is no need to instantiate any object?

Follow-up question:

Is it possible to do this without having to pass an object to this function? Right now I am passing an object of type outer<inner> to get_inner_t . I would like to avoid this and retrieve inner with the help of template metaprogramming only.

My approach: 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;
}

Yes it is possible. Just use a template class (struct here) instead of the template function. And retrieve the type of the object with decltype and pass it to the template class.

The following is one way to do it:

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

This way you don't need to pass the object itself but its type only. I guess this also works for abstract types too.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM