#include <iostream>
#include <vector>
using namespace std;
struct Foo {
size_t length() { return 1; }
};
struct Bar {
void length();
};
template <typename R, bool result = std::is_same<decltype(((R*)nullptr)->length()), size_t>::value>
constexpr bool hasLengthHelper(int) {
return result;
}
template <typename R>
constexpr bool hasLengthHelper(...) { return false; }
template <typename R>
constexpr bool hasLength() {
return hasLengthHelper<R>(0);
}
template <typename R>
typename std::enable_if<hasLength<R>(), size_t>::type lengthOf (R r) {
return r.length();
}
int main() {
std::cout << hasLength<Foo>() << "; " << hasLength<std::vector<int>>() << "; " << hasLength<Bar>() << "\n";
std::cout << lengthOf(Foo()) << std::endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKc3RydWN0IEZvbyB7CglzaXplX3QgbGVuZ3RoKCkgeyByZXR1cm4gMTsgfQp9OwoKc3RydWN0IEJhciB7Cgl2b2lkIGxlbmd0aCgpOwp9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIFIsIGJvb2wgcmVzdWx0ID0gc3RkOjppc19zYW1lPGRlY2x0eXBlKCgoUiopbnVsbHB0ciktPmxlbmd0aCgpKSwgc2l6ZV90Pjo6dmFsdWU+CmNvbnN0ZXhwciBib29sIGhhc0xlbmd0aEhlbHBlcihpbnQpIHsgCglyZXR1cm4gcmVzdWx0Owp9CiAKdGVtcGxhdGUgPHR5cGVuYW1lIFI+CmNvbnN0ZXhwciBib29sIGhhc0xlbmd0aEhlbHBlciguLi4pIHsgcmV0dXJuIGZhbHNlOyB9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgUj4KY29uc3RleHByIGJvb2wgaGFzTGVuZ3RoKCkgewoJcmV0dXJuIGhhc0xlbmd0aEhlbHBlcjxSPigwKTsKfQoKdGVtcGxhdGUgPHR5cGVuYW1lIFI+CnR5cGVuYW1lIHN0ZDo6ZW5hYmxlX2lmPGhhc0xlbmd0aDxSPigpLCBzaXplX3Q+Ojp0eXBlIGxlbmd0aE9mIChSIHIpIHsKICByZXR1cm4gci5sZW5ndGgoKTsKfQoKaW50IG1haW4oKSB7CglzdGQ6OmNvdXQgPDwgaGFzTGVuZ3RoPEZvbz4oKSA8PCAiOyAiIDw8IGhhc0xlbmd0aDxzdGQ6OnZlY3RvcjxpbnQ+PigpIDw8ICI7ICIgPDwgaGFzTGVuZ3RoPEJhcj4oKSA8PCAiXG4iOwoJc3RkOjpjb3V0IDw8IGxlbmd0aE9mKEZvbygpKSA8PCBzdGQ6OmVuZGw7CglyZXR1cm4gMDsKfQ==