List with multiple template

Pages: 12
Good evening to everyone,
I'm opening this topic because i need to solve a problem with templates in lists.

I need to create a list which can contain for each cell a different type of variable. So, something like this:

List: int i_variable
char c_variable
float f_variable

where every rows describes a single list cell.
The order and the cells number is totally decided from keyboard so there is no possible scheme. I tried to used templates but i didn't find a way to create different types, just one for each list.
I hope i have been clear enough in my problem description.
There is also my first topic in this forum so i hope i have not make mistakes.

Thanks everyone who try to help me!
Last edited on
You would need each element of the list to be a template, not the list itself. You can create some generic list_element class and have it be a template that stores a particular value.
how can i create a generic list element?
until now my list definition was like: list<my_class<T>>

and before reading your answer i found the "variant" function, could it be usefull in my case?
std::any might be the way to go.
https://en.cppreference.com/w/cpp/utility/any
Unfortunately i cannot use it, it is only from c++17, i can only use c++11.
I know that there is a usefull library called boost but i cannot use it too.
I forgot to specify it sorry.

I cannot find any way to figure this out.

(I read in the form rules that i cannot ask for helps with homework or something like that, so i need to specify that i've got this rules to follow because i'm making a bigger project and this is only a little part which i cannot figure out, so i'm not cheating)
and before reading your answer i found the "variant" function, could it be usefull in my case?


You also realize that std::variant is from C++17 as well, right? In any case, what compiler are you using? You should be able to use C++17 features with a compiler flag provided that your compiler is up to date.

If you cant, then you can just use the generic list_element method I mentioned. Something like this should give you an idea of what I mean:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <vector>
#include <string>

struct list_element
{
};

template<typename T> 
struct list_element_type : list_element
{
        list_element_type(T const& val) : elem(val) {}
        T elem;
};
std::vector<list_element> the_list;


int main()
{
    the_list.push_back(list_element_type<int>{43});
    the_list.push_back(list_element_type<std::string>{"HELLO"});
}
Last edited on
You also realize that std::variant is from C++17 as well, right? In any case, what compiler are you using? You should be able to use C++17 features with a compiler flag provided that your compiler is up to date.


Exactly i'm not able to use it too.

what i don't understand is what do you mean with "generic list_element method" i couldn't find it anywhere surfing on the internet. Could explain it to me or giving some reference?
Last edited on
I gave you example code. What compiler do you use?
I gave you example code. What compiler do you use?


yes thank you so much, i'm trying to test and undestand your code. Sorry, i'm a bit slow in answering.

I'm using visual studio as ide, the compiler is the default one.
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <vector>
#include <string>

struct list_element
{
};

template<typename T> 
struct list_element_type : list_element
{
        list_element_type(T const& val) : elem(val) {}
        T elem;
};
std::vector<list_element> the_list;


int main()
{
    the_list.push_back(list_element_type<int>{43});
    the_list.push_back(list_element_type<std::string>{"HELLO"});


Well, i find this code hard to understand with my c++ knowledge, i need to take some time to analise it properly.
I don't understand the row 11. What does that code line?
Last edited on
Honestly this isn't the best code. I haven't tested it and its probably very ugly to use. You can't access the types after insertion either unless you use a very ugly static_cast. It would be better to use std::any or std::variant, or try to implement a discriminated union type

Line 11 declares a constructor that initializes the elem member to the value passed in by the user.
Last edited on
Correct me if i'm wrong but this code doesn't allow me to take back and modify my data into that variables, does it?

It would be better to use std::any or std::variant, or try to implement a discriminated union type

Unfortunately i have to avoid this solutions.

I'm trying to realise it with union, i'll post here my idea as soon as i can!
You can make your own implementation of std::any or some discriminated union. Another option is to use std::tuple if you know the types and size beforehand.
Last edited on
Here i am.
You can make your own implementation of std::any or some discriminated union. Another option is to use std::tuple if you know the types and size beforehand.

No my data comes from a template so i don't know what type is beforehand.
I think that might be work the union for my problem. If i will not figure out with this i will try create my own any.

here is it what i produced:
1
2
3
4
5
6
7
8
9
10
11
12
13
union possibilities {
	int i;
	char c;
	float f;
};

vector <possibilities> my_vector;

int main() {
       myvector.push_back(10);
       myvector.push_back('a');
       
}


What i understood from my research is that i can assign one of the variables in union at time. so i was thinking that my line code into the main would be right, but it is not working. What i'm doing wrong?
Last edited on
Your vector takes possibilities objects. You are passing it an int and a char.
1
2
3
4
5
6
7
8
9
10
11
12
#include <vector>
union possibilities {
	int i;
	char c;
	float f;
};

std::vector <possibilities> myvector;

int main() {
       myvector.push_back(possibilities{10});       
}


You probably shouldn't use this option because you can't access specific values without knowing the type that was recently accessed. Otherwise you have undefined behavior if you try to access a different type. Instead, you should implement your own discriminated union type as a wrapper around union.

On a side note, what do you have against using C++17? It would be extremely easy to set up. Most likely your compiler already supports it, you would just have to enable it in the compiler settings.
Last edited on
I undestand, so your saying that i can't manage data after have insert it inside the vector beacuse i don't know which type of data i've inserted in that position.

May i find a way to save into a flag the type of that position, having so the possibility to get the right variables?


On a side note, what do you have against using C++17? It would be extremely easy to set up. Most likely your compiler already supports it, you would just have to enable it in the compiler settings.


This project i'm working on is requested from others, and in their request specified that need to be implemented only with c++11. This is causing me some trouble to figure out like this one!
Last edited on
Yes, you would need to implement a discriminated union/tagged union like std::variant like I said.
perfect i think i'm reaching my goal. Just the last question, in the example we discuss before we define

myvector.pushback(possibilities{10})

in order to use that data content i need to do this

myvector[0].i that returns 10.

Now, my question is: ignoring the index vector which i can manage with index or iterators, can i use a smartest way to get "10"? for example without the need to specify "i" variables at 0 position?

something that should works ipotetically like myvector[0] and returns "10"
Last edited on
I responded to that. You would need to make a custom wrapper around the union like a discriminated union/tagged union so that you don't have to access the "i" member.
What about storing the data in a string? Would be easy to determine if it is a float or int.
Pages: 12