Reputation: 2015
I am wanting to make a template function that adds three numbers. The type may be int or char or string. How can I add these then return the correct value using the same type. Example: three strings of numbers {5,6,7} should add up to 18 then return 18 as a string. three chars of numbers {5,6,7} should add up to 18 then return 18 as a char.
template <class MyType>
MyType GetSum (MyType a, MyType b, MyType c) {
return (a+b+c);
}
int a = 5, b = 6, c = 7, d;
char e = '5', f = '6', g = '7', h;
string i= "5", j= "6", k= "7", l;
d=GetSum<int>(a,b,c);
cout << d << endl;
h=GetSum<char>(e,f,g);
cout << h << endl;
l=GetSum<string>(i,j,k);
cout << l << endl;
This code works for int but obviously not for char or string. I am not sure how to convert from an unknown type to int and back so i can add the numbers.
Upvotes: 0
Views: 2499
Reputation: 70382
You can implement explicit conversion template functions, where each is implemented with template specialization. For instance:
template <typename MyType> int ToInt (MyType);
template <> int ToInt<int> (int x) { return x; }
template <> int ToInt<std::string> (std::string x) { return std::stoi(x); }
template <> int ToInt<char> (char x) { return std::stoi(std::string(&x, 1)); }
template <typename MyType> MyType FromInt (int);
template <> int FromInt<int> (int x) { return x; }
template <> std::string FromInt<std::string> (int x) {
std::ostringstream oss;
oss << x;
return oss.str();
}
template <> char FromInt<char> (int x) {
static const std::string map("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ");
return map.at(x);
}
Then, the GetSum()
would call ToInt<>()
on the arguments, compute the sum, and then call FromInt<>()
to convert the value back to the original type:
template <typename MyType>
MyType GetSum (MyType a, MyType b, MyType c) {
int aa = ToInt(a);
int bb = ToInt(b);
int cc = ToInt(c);
return FromInt<MyType>(aa + bb + cc);
}
As can be seen in this demo, for your same program, the output is:
18
I
18
The reason for I
for the char
case is that the conversion assumes the resulting value can be expressed as a single base 36 digit.
Upvotes: 0
Reputation: 10345
You want addition as if the items would be integers though may be int, char or std::string.
That means, first get them to be integers, then convert back to the original type:
template <typename T>
T sum(T t1, T t2, T t3)
{
std::stringstream input;
input << t1 << " " << t2 << " " << t3;
int sum = 0;
int item;
while ( input >> item )
{
sum += item;
}
// at this point we have the wanted value as int, get it back in a general way:
std::stringstream output;
output << sum;
T value;
output >> value;
return value;
}
I'd be a bit careful with the addition of char
s in that way. '18'
isn't exactly meaningful afaik, or probably at least platform dependent.
You'll need to include <sstream>
in your project to use std::stringstream
.
Upvotes: 2
Reputation: 28241
You can use boost::lexical_cast
to convert between integer and string types.
template <class MyType>
MyType GetSum (MyType a, MyType b, MyType c)
{
int int_a = boost::lexical_cast<int>(a);
int int_b = boost::lexical_cast<int>(b);
int int_c = boost::lexical_cast<int>(c);
int sum = int_a+int_b+int_c;
return boost::lexical_cast<MyType>(sum);
}
If you are not allowed, or don't want, to use boost
, just implement the function template lexical_cast
yourself (you will have to implement several template specializations, but each individual one is easy).
Upvotes: 0