2

I have two types, call them A and B. I want to ensure that future developers do not change these types in such a way that they can compare equal.

To do so, I would like to add a unit test and a static_assert that ensure this property. I am in c++03, and I have tried various template tricks like the following.

template <class Left, class Right>
struct can_compare_equal {
   typedef char True;
   typedef long False;

   template <class U>
   static U GetT() { Left* l; Right* r; return *r == *l; }

   template <class U> static True test(typeof(&can_compare_equal<Left,Right>::GetT<U>));
   template <class U> static False test(...);

   enum { value = sizeof(test<True>(0)) == sizeof(char) };
};

Unfortunately I can't get it to compile correctly. Any advice?

JRG
  • 2,065
  • 2
  • 14
  • 29
  • The body of a method or function does not prevent it from being found, it just makes it an error to be found. Have you thought about upgrading your compiler? ;) – Yakk - Adam Nevraumont Mar 24 '15 at 14:22
  • @Yakk: not really possible. I'm stuck with gcc 4.2.1. Also it should be possible: http://stackoverflow.com/questions/257288/is-it-possible-to-write-a-c-template-to-check-for-a-functions-existence – JRG Mar 24 '15 at 14:24
  • Ah, easy! Compile gcc 4.9.2 with gcc 4.2.1. Problem solved! (I kid) A problem is that `==` is not "a function", but rather an invocation of an operator. It could call a method, a function in some namespace, be found via ADL: heck it can be found via ADL in a way that there is guaranteed to be no other way to find it other than via ADL (the `friend operator` trick). The linked answer detects if a given class has a non-overridden method of a given name: it does not work in general! `struct Evil{void a(){};void a(int){};};` That is not sufficient to determine if `A==B` is a valid expression. – Yakk - Adam Nevraumont Mar 24 '15 at 14:26
  • Good point. I am really looking to ensure that no one does something dumb like make `A` derive from `B` or add an `A::operator==(const B&)`. I guess I need to sharpen my question – JRG Mar 24 '15 at 14:36
  • then just `is_base_of` + `has_method_operator==_with_signature_blah` x2? That reduces your question to a dupe of what you linked, no? The general case cannot be solved in C++03, and the specific case is just a matter of which combination of specific cases (already solved) you want to cover. – Yakk - Adam Nevraumont Mar 24 '15 at 14:38
  • Can't you just write your own version of `std::is_same`? – edmz Mar 24 '15 at 14:39
  • @black; that is not what I'm looking for. My original question was broader than "are these types the same up to cv qualifiers". See my previous comment starting with "Good point" – JRG Mar 24 '15 at 14:42
  • @JRG I see. Anyways, does the fact that you use `typeof` (which is a GCC extension) mean we can use other compiler-specific things? – edmz Mar 24 '15 at 14:57
  • The answer to this question would work (Add a template parameter to check between two differents types) : http://stackoverflow.com/questions/6534041/how-to-check-whether-operator-exists – Johnmph Mar 24 '15 at 16:02
  • @Johnmph, this will work for non-member functions, I'm checking to see if it's modifiable to recognize `A::operator==(const B&) const` – JRG Mar 24 '15 at 18:44
  • 1
    @JRG It should work with member functions too. https://ideone.com/a0oBA0 – Johnmph Mar 24 '15 at 23:25

0 Answers0