fork download
  1. #include <type_traits>
  2. #include <iostream>
  3.  
  4. struct C {};
  5.  
  6. int size (const C & c) {
  7. std::cout << "global size!\n";
  8. return 0;
  9. }
  10.  
  11. template <typename B>
  12. class has_size
  13. {
  14. // This type won't compile if the second template parameter isn't of type T,
  15. // so I can put a function pointer type in the first parameter and the function
  16. // itself in the second thus checking that the function has a specific signature.
  17. template <typename T, T> struct TypeCheck;
  18.  
  19. typedef char Yes;
  20. typedef struct { char dummy[2]; } No;
  21.  
  22. // A helper struct to hold the declaration of the function pointer.
  23. // Change it if the function signature changes.
  24. template <typename T> struct Size
  25. {
  26. typedef int (T::*fptr)(const C&);
  27. };
  28.  
  29. template <typename T> static Yes HasSize(TypeCheck< typename Size<T>::fptr, &T::size >*);
  30. template <typename T> static No HasSize(...);
  31.  
  32. public:
  33. static bool const value = (sizeof(HasSize<B>(0)) == sizeof(Yes));
  34. };
  35. template <class B>
  36. int callSize(B* obj, const C& c, typename std::enable_if<has_size<B>::value>::type* = 0)
  37. {
  38. obj->size(c);
  39. }
  40. template <class B>
  41. int callSize(B*, const C& c, typename std::enable_if<!has_size<B>::value>::type* = 0)
  42. {
  43. return size(c);
  44. }
  45.  
  46.  
  47. struct B
  48. {
  49. int size () { /* ... */ };
  50.  
  51. template <class U> friend int ::callSize(U*, const C&, typename std::enable_if<has_size<U>::value>::type*);
  52. template <class U> friend class has_size;
  53. void doSomething (const C & c)
  54. {
  55. int x = ::callSize(this, c); // <----------- problem!
  56. // ...
  57. }
  58. private:
  59. #ifdef LOCAL_SIZE
  60. int size (const C & c) {
  61. std::cout << "local size!\n";
  62. return 0;
  63. }
  64. #endif
  65. };
  66.  
  67. int main() {
  68. B b;
  69. b.doSomething(C());
  70. }
Success #stdin #stdout 0s 2884KB
stdin
Standard input is empty
stdout
global size!