Let's imagine a situation like this. We have a function that performs some sort of calculations. The result can be either 1,2 or 3. Depending on the result we want to return different values. Let's say if the outcome is 1, the return will be 1 (integer). For 2 it will be 2.1452 (float), and for three it will be 'A' (char). Therefore we cannot predict what type will be returned. I thought of using a union, but so far so unsuccessful. This is what I have for now (it won't compile):
union myType {
int number;
float point;
char letter;
};
myType fun ()
{
int val=rand()%3+2;
switch (val)
{
case 1:
fun().number=1;
return fun().number;
case 2:
fun().point=2.14;
return fun().point;
case 3:
fun().letter='A';
return fun().letter;
}
}
My workaround (which I don't want to use) -depending on the situation- is to return int or float and then cast it, but as I said- I am seeking a solution without casting, because it's not always suitable.
It doesn't really make sense though. You have absolutely no way to know the difference between these things. 2.14 will be stored in memory as 0x4008f5c3, which you won't be able to differ from an integer 1,074,329,027.
You might as well just return a float always, with values 1, 2.14, or 65
The return type of a function shall be known at compilation time. You can return a union but you should declare one more data member of the union that will be point out what exactly data member of the union contains the result.
For example
1 2 3 4 5 6 7 8 9 10
struct Result
{
enum { INT, FLOAT, CHAR } kind;
union
{
int number;
float point;
char letter;
};
};
I know I can always return a float and then cast it to whatever I want, but it's an exercise. Let's say that for some reason I can't force it to return float.
@ResidentBiscuit Could you write such a template? I'd like to step my game up :-D
Result GetRandomValue()
{
Result r;
int Val = rand()%3;
switch(Val)
{
case 0:
r.kind = INT;
r.number = 2;
return r;
case 1:
r.kind = FLOAT;
r.point = 3.5f;
return r;
case 2:
r.kind = CHAR; // Remember that for a character you can just use a int.
r.number = 'a';
return r;
}
r.kind = INT;
r.number = 0;
return 0;
}
#include "stdafx.h"
#include <iostream>
struct Result
{
enum { INT, FLOAT, CHAR } kind;
union
{
int number;
float point;
char letter;
};
};
Result GetRandomValue()
{
Result r;
int Val;
Val = std::rand() % 3;
switch ( Val )
{
case Result::INT:
r.kind = Result::INT;
r.number = 2;
break;
case Result::FLOAT:
r.kind = Result::FLOAT;
r.point = 3.5f;
break;
case Result::CHAR:
r.kind = Result::CHAR;
r.number = 'a';
break;
}
return ( r );
};
int _tmain(int argc, _TCHAR* argv[])
{
Result r = GetRandomValue();
switch ( r.kind )
{
case Result::INT:
std::cout << "It is an integer and equal to " << r.number;
break;
case Result::FLOAT:
std::cout << "It is a float and equal to " << r.point;
break;
case Result::CHAR:
std::cout << "It is a character and equal to " << r.letter;
break;
}
std::cout << std::endl;
}