简体   繁体   English

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

[英]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 .对于std::shared_ptr<int>我想得到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.这在某些情况下不起作用,例如std::shared_ptr<some_abstract_class>或默认构造函数被删除。

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 .现在我将一个类型为outer<inner>的对象传递给get_inner_t I would like to avoid this and retrieve inner with the help of template metaprogramming only.我想避免这种情况并仅在模板元编程的帮助下检索inner

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.并使用decltype检索对象的类型并将其传递给模板类。

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.我想这也适用于抽象类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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