#include <iostream>

template <typename T>
class has_size {
private:
  typedef char Yes;
  typedef Yes No[2];

  template <typename U, U> struct really_has;

  template<typename C> static Yes& Test(really_has <size_t (C::*)() const, &C::size>*);
  template<typename C> static Yes& Test(really_has <size_t (C::*)(), &C::size>*);
  
  template<typename> static No& Test(...);

public:
    static bool const value = sizeof(Test<T>(0)) == sizeof(Yes);
};

struct NoSize {};

struct Sized { size_t size() const { return 0; } };

struct MutableSized { size_t size() { return 0; } };

struct BadlySized { int size() { return 0; } };

struct MultiSized { size_t size() const { return 0; } int size(int) { return 0; } };

int main() {
  std::cout << "NoSize: " << has_size<NoSize>::value << "\n";
  std::cout << "Sized: " << has_size<Sized>::value << "\n";
  std::cout << "MutableSized: " << has_size<MutableSized>::value << "\n";
  std::cout << "BadlySized: " << has_size<BadlySized>::value << "\n";
  std::cout << "MultiSized: " << has_size<MultiSized>::value << "\n";
}