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, e.g. 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:
This way you don't need to pass the object itself but its type only. I guess this also works for abstract types too.