0

I'm a C++ novice, and I'm essentially trying to figure out if I can use an STL container as a template which stores whatever type is being passed into it. I don't know if I need to use a class template or define a unique struct or what.

Here's essentially what I have, along with some commentary on what I'd like to achieve:

std::deque<template class T> messages; <--- ???

//the goal being not to store ANY type in this deque, but to somehow
//template it for each type that needs to be stored
//e.g. a different deque for an int, bool, ADT, etc.

template<class T> bool StoreMessage(T const &messageToStore){
     messages<T>.push_back(messageToStore);
}

I have no idea how to even approach this or if this is even possible, but I really don't want to have to write functions for each type that needs to be stored, because there are a lot. Or use void*. I don't want to do that either due to safety and I would still have to explicitly define how to handle each type, even though the process is going to be exactly the same.

Thanks, guys!

dlar
  • 21
  • 3
  • 4
    The `std::deque` already works the way you want it to, unless I have completely misunderstood you. – Galik May 26 '16 at 18:28
  • The standard **template** library (which is [no longer the proper name of it](https://stackoverflow.com/questions/5205491/whats-this-stl-vs-c-standard-library-fight-all-about)) already uses templates for most (all?) of the containers. – Cory Kramer May 26 '16 at 18:29
  • @Galik I get that a deque can already store any type, but I didn't think that the deque itself was templated. The goal is to have a deque member variable which is templated to store whatever is passed into the method. Using deque as a member variable gives compiler errors because T isn't a type of my class. – dlar May 26 '16 at 18:33
  • So you want *one* deque to hold instances of *different* types? How do you intend on pulling the types out? What do you intend on doing with `messages` in the future? – Barry May 26 '16 at 18:55
  • @Barry No, sorry, I'm bad at explaining. I wanted to *declare* one deque in a header but use a different deque for each type passed in, without having to explicitly define what type I'm using. e.g. if I need to store ints and floats, I can store them separately without defining deque and deque, if that makes any sense. I think Wojciech's answer in wrapping the deque in a template container is the best solution. – dlar May 26 '16 at 19:48

2 Answers2

3

Containers are already templated, so what you are trying to do is probably something like this:

template <typename T>
bool store_message(const T &message, std::deque<T> &container) {
    container.push_back(message);
}

To call it, pass both a container by reference and the element:

std::deque<int> numbers;
int el = 5;

store_message(el, numbers);
Franko Leon Tokalić
  • 1,457
  • 3
  • 22
  • 28
  • So would I have to create a deque for each data type as I use it? The deque is a member variable of a non-templated class as I have it right now. – dlar May 26 '16 at 18:33
  • Yes, the containers of types somehow need to be defined somewhere. You could probably find a way not to do it manually. – Franko Leon Tokalić May 26 '16 at 18:34
  • I was defining it in my .h file as deque, but that doesn't work since T isn't a member of my base class. I guess I was just trying to see if I could template the deque itself, not store whatever type in a deque. – dlar May 26 '16 at 18:39
  • @dlar Check Wojciech Frohmberg's answer, that solves your problem of defining a deque for each type, quite clever – Franko Leon Tokalić May 26 '16 at 18:51
0

Actually you can do something like:

#include <deque>

template <class T>
struct container {
   static std::deque<T> messages;
};

template <class T>
std::deque<T> container<T>::messages;

template<class T> bool StoreMessage(T const &messageToStore){
     container<T>::messages.push_back(messageToStore);
}

int main() {
   int a = 10;
   StoreMessage(a);
}

So you want to wrap your variable over additional templated structure and put it into static variable. You need to however declare the static variable to compiler allocate memory to this variable. This is done in lines: template <class T> std::deque<T> container<T>::messages;. To do it properly remember to move everything what is templated to a header file including the memory allocating/declaring stuff... This way you'll be able to access the messages among all your cpp/cc files. All you need to do is to include your created header file in it.

W.F.
  • 13,888
  • 2
  • 34
  • 81
  • Wow, this seems to work perfectly. Will I be able to remove the static aspect of this and make the deque unique to each instance of an object? I'm using it in a base class to where a derived class stores whatever message type, but I don't want those messages of the same type to be stored in the same container (e.g. Y and Z both derive from X and both store ints, so I would like Y to have its own X::container and Z to have its own X::container) or is this not possible? If not, I'll have to use a different design. – dlar May 26 '16 at 19:34
  • @dlar I think you could make a container depended on both type of the message and the type of your related variable, so you could create sth like `container::message` and it would make it possible... I think... – W.F. May 26 '16 at 19:58
  • Couldn't tell you, dude. You've been more than helpful, and I don't even have 15 rep to affect the public score yet. I'm going to look into seeing if I can modify your solution to make it work for what I need. Thanks again, man! I kind of understand what I'm doing now. – dlar May 26 '16 at 20:42
  • @dlar Well I guess my answers are not very popular recently, don't worry - not your fault :) – W.F. May 26 '16 at 20:44
  • Not the downvoter, but an issue with this answer is that it's not exactly equivalent to having two different member queues, since the queues are static. – user2296177 May 26 '16 at 21:18
  • @user2296177 you gonna get as many deques as many different type params you pass to template. If you want to do it less singletonish you could store in container struct map of deques with appropriate key type to map your dynamic objects to given deque – W.F. May 26 '16 at 21:35