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.
Oh okay, i didn't get that @TheToaster, i'm collecting some information about a custom wrapper.
What about storing the data in a string? Would be easy to determine if it is a float or int.
I need to be carefull with memory occupation, probably my vector<union> will be pretty bigger so I think that storing other space for a string for each union inside the vector could be a bit heavy. Do you agree or you think that this method would be easier and helpful? @Thomas1965
SideNote: i'm using other types over float and int that are own created, here i'm generalising my problem
Goodmorning everyone! Finally i can update this topic.
I managed to create my code. Unfortunately my compliler is giving me an error that i can't figure out. I hope this is the last modify that i need to do!
enum allowed_type { INT = 'i', FLOAT = 'f', CHAR = 'c' };
struct mystruct {
char tag; // contain the type identifier
union types {
int i;
float f;
char c;
} u;
mystruct() { // union constructor
u.i = 0;
u.f = 0;
u.c = 'a';
}
~mystruct() { // union destructor
if (tag == INT)
s.i.~int_destructor();
elseif (tag == FLOAT)
s.f.~float_destructor();
elseif (tag == CHAR)
s.c.~char_destructor();
}
template <typename T> record<T>* GetValue() {
switch (static_cast<allowed_type>(tag)) {
case INT: return s.i;
case FLOAT: return s.f;
case CHAR: return s.c;
default: throw invalid_argument("Error");
break;
}
}
};
My problem is that in a part of my code i need to insert into one of the union variables a template content, which can be one of that 3 types into union.
I've implemented it in this way:
the compiler stops me because is saying that when i'm trying for example to assign the template_variable to help.s.i, i'm trying to assign a float and a char type too, which is obviously invalid. Where could be my fault?
You can also just overload the function that assigns to the particular variable:
1 2 3
void set(int);
void set(char);
void set(float);
Unfortuantly, your GetValue method won't exactly work as expected. A function cannot return values of different types. There is a way to make the return type "auto" but even doing so would require that the return value can be deduced at compile time, which it can't because it can change. The user would have to specifically call the function with the type that they expect, like so:
int x = my_variant.get<int>();
You can, theoretically, use exception throwing to "emulate" different return types but that is a horrible abuse of exception handing's purpose and intent.
Well, I got your point. I delete GetValue() and use switch directly where I need it (was just in a single place, lucky me).
Then, considering that I can't do int x = my_variant.get<int>(); in my program as I made it, I find a way that seems to work but i defenetly need your opinion. Whereas when i call template_variable into the switch i know which type is it. so i decide to proceed in this way:
help.s.c = reinterpret_cast<char>(template_variable)
(example for char case)
For sure this solution works, because it is working, but using this reinterpret cast forcing the variable doesn't convice me very much
What exactly are you doing with "template_variable"? Post all the code you use in your implementation here.
As I said, it would be infinitely easier to have separate overloads to set each value, like I mentioned in the previous comment. Alternatively, you could use some metaprogramming and handle each case:
To clear exactly what i'm doing with template_variable i should post here about 500 code lines, because template_variable is a template_object create from a class.
Probably i'll be to much confusing if i'll post and try to explain all of that.
it would be infinitely easier to have separate overloads to set each value
I agree with you but whereas variable_template it is not a simple variable i found hard following this way.
Alternatively, you could use some metaprogramming and handle each case: