Search code examples
c++templatesc++11decltype

storing and re-using decltype value?


if I have a template:

template <class T>
struct Item
{
  T _value;
};

I can then do:

// ...
Item<int> x = { 42 }; // declared as an int

// ...
decltype(x._value) y = 20; // 'y' is also an int

But is it possible to store the decltype to a variable so it can be used later?

Why?
I want to store the values of items as pointer.

Something like std::vector<Item*> but as they are templates I have to store them as pointers to void:

std::vector<void*> is;
is.push_back(new Item<int>());
is.push_back(new Item<double>());
is.push_back(new Item<float>());

And this is all fine, but when it comes time to delete the pointer I need to re-cast my void* back to the proper type (so the destructors are called):

delete (Item<int>*)is[0];

And if I know the type, I could do:

delete (Item<decltype(whatever)>*)is[0];

Hence the reason I would need to store the decltype.

I hope this makes sense.


Solution

  • decltype is a language feature that allows you to retrieve a type at compile-time. It seems that you want to "store" that type so that you can correctly delete objects allocated on the dynamic storage at run-time. Assuming that's the case, decltype is not going to help here.

    You have various options:

    1. Use some form of type-erasing facility like Boost.Variant or Boost.Any, as suggested by Baum mit Augen in the comments.

    2. Make your objects part of a polymorphic hierarchy and use smart pointers:

      struct ItemBase 
      {
          virtual ~ItemBase() { }
      };
      
      template <class T>
      struct Item : ItemBase
      {
          T _value;
      };
      
      int main() 
      {
          std::vector<std::unique_ptr<ItemBase>> items;
          items.emplace_back(std::make_unique<Item<int>>());
          items.emplace_back(std::make_unique<Item<float>>());                     
          items.emplace_back(std::make_unique<Item<double>>());
      }