16

I need to implement self contained compile-time function for checking type equality (function template without arguments bool eqTypes<T,S>()).

self contained means not relying on library.

I'm not good in all this. That's what I tried, but it's not what I need.

template<typename T>
bool eq_types(T const&, T const&) { 
return true;
}

template<typename T, typename U> 
bool eq_types(T const&, U const&) { 
return false; 
}
Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
Roman2452809
  • 378
  • 1
  • 2
  • 17
  • 3
    Are you allowed to use [`std::is_same`](http://en.cppreference.com/w/cpp/types/is_same)? – juanchopanza Jun 04 '13 at 17:45
  • http://stackoverflow.com/a/3450395/168175 shows how to implement it yourself, but it would need (trivially) adapting to be a function instead of a struct. – Flexo Jun 04 '13 at 17:45

3 Answers3

31

It's quite simple. Just define a type trait and a helper function:

template<typename T, typename U>
struct is_same
{
    static const bool value = false;
};

template<typename T>
struct is_same<T, T>
{
    static const bool value = true;
};

template<typename T, typename U>
bool eqTypes() { return is_same<T, U>::value; }

Here is a live example.

In C++11, if you are allowed to use std::false_type and std::true_type, you would rewrite the above this way:

#include <type_traits>

template<typename T, typename U>
struct is_same : std::false_type { };

template<typename T>
struct is_same<T, T> : std::true_type { };

template<typename T, typename U>
constexpr bool eqTypes() { return is_same<T, U>::value; }

Notice, that the type trait std::is_same, which does pretty much the same thing, is available as part of the Standard Library.

Andy Prowl
  • 124,023
  • 23
  • 387
  • 451
  • Might as well `constexpr bool eqTypes()`. – Timothy Shields Jun 04 '13 at 17:51
  • @TimothyShields: True, I was assuming C++03 was the target. I will add a C++11-ish version – Andy Prowl Jun 04 '13 at 17:52
  • @liuml07: Can you elaborate on your statement? I'm not sure what you mean here – Andy Prowl Jun 04 '13 at 17:55
  • @AndyProwl I don't know the expected answer of the `eqTypes()`. I suppose it be `true`. The `std::is_same` can't work for this either. If the expected answer is `false`, it looks good. – Mingliang Liu Jun 04 '13 at 17:59
  • @liuml07 Are you talking about a `base *` and a `derived *` returned by `typeof` on two pointers pointing to the same `derived` object? Those are indeed different types, so I'm not sure I would say it "doesn't work". What about a `void *` and `int *` both pointing to an `int`, would you expect that to return `true`? – jerry Jun 04 '13 at 17:59
  • 1
    @liuml07: `eqTypes()` should return `false` indeed. That's supposed to check whether the types are *equal*, not whether one is convertible to the other, or derived from the other, and so on - there are other type traits that serve those purposes – Andy Prowl Jun 04 '13 at 18:01
  • @AndyProwl: Right. It's straightforward to return `fasle` on second thought. – Mingliang Liu Jun 04 '13 at 18:05
4

Here's how you can do it in C, without any magic GCC extensions:

#define CHECKED_TYPE(original_type, p) ((conversion_type*) (1 ? p : (original_type*) 0))

E.g:

void *q = CHECKED_TYPE(int, &y);

Will trigger a compile error if y is not int.
For explanation, see here.

Igor Skochinsky
  • 24,629
  • 2
  • 72
  • 109
0
#define CHECK_TYPE_EQUAL(type_a, type_b) { \
    type_a type_a##_var __attribute__((unused)); \
    type_b *type_b##_ptr __attribute__((unused)); \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic error "-Wincompatible-pointer-types\"") \
    type_b##_ptr = &type_a##_var; \
_Pragma("GCC diagnostic pop") \
}