Wednesday, May 11, 2011

Checking if variables are of certainin type in C++

Okay this problem is something I often see people do incorrectly in c++.

I've seen people use the sizeof() operator to try and distinguish types such as:
template<typename T> void foo(T x) {
if (sizeof(x) == sizeof(string)) cout << "x is a string\n";
if (sizeof(x) == sizeof(char)) cout << "x is a char\n";
if (sizeof(x) == sizeof(int)) cout << "x is a int\n";

The above is obviously wrong because different types can have the same size. In many 32bit implementations sizeof(std::string) will be equal to sizeof(int).

Now how can we do this better?
Well there's a few ways to do this, one way can be to use template specialization for each of the above cases and make separate functions.

But I'll explain another way. Boost has a templated struct called is_same which we can use in this case. However if you're like me and don't like using a lot of dependencies or over-engineered libraries in your code, then we can write our own code to tell us if two types are the same or not.
It looks like this:
template<typename A, typename B>
struct _isSame { static const bool value = false; };
template<typename A>
struct _isSame<A, A> { static const bool value = true; };

We can now use the above code like this:
template<typename T> void foo(T x) {
if (_isSame<T, string>::value) cout << "x is a string\n";
if (_isSame<T, char>::value) cout << "x is a char\n";
if (_isSame<T, int>::value) cout << "x is a int\n";

Lastly, we can make a helper function that lets us know if two variables are of the same type.
template<typename A, typename B>
inline bool isSame(A a, B b) { return _isSame<A, B>::value; }

And here's an example using the above function:
int main() {
int x = 0;
int y = 0;
float z=0;

cout << "Is x's type the same as y's type? ";
cout << (isSame(x, y) ? "Yes" : "No") << endl;

cout << "Is x's type the same as z's type? ";
cout << (isSame(x, z) ? "Yes" : "No") << endl;

No comments:

Post a Comment