#include <iostream>
#include <vector>
#include <type_traits> //needed for enable_if?
using namespace std;
template<class T> struct supports_iteration
{
private:
typedef char yes[1];
typedef char no[2];
template <class C> static yes& foo(typename C::iterator*);
template <class C> static no& foo(...);
public:
static constexpr bool value = sizeof(foo<T>(0)) == sizeof(yes);
};
template<template <class, class> class C, class T, class A>
void DoSomething(C<T,A>& val)
{
T* pT;
cout << "did something!\n";
}
template<template <class, class> class C, class T, class A>
void DoSomethingSmartly(
typename std::enable_if<
supports_iteration<
C<T,A>
>::value
>::type& val)
{
T* pT;
cout << "did something smartly!\n";
}
template<template <class, class> class C, class T, class A,
typename = decltype(
declval<C<T,A>>().size()
,void()
)
>
void DoSomethingReallySmartly(C<T,A>& val)
{
T* pT;
cout << "did something really smartly!\n";
}
int main() {
// your code goes here
vector<int> v{1,2,3,4,5};
DoSomething(v);
cout << "vector<int> supports_iteration? " <<
boolalpha << supports_iteration<decltype(v)>::value << "!" << endl;
//DoSomethingSmartly(v);// - fails!!
//template argument deduction/substitution failed:
//couldn't deduce template parameter ‘template<class, class> class C’ DoSomethingSmartly(v);
DoSomethingReallySmartly(v);
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+IC8vbmVlZGVkIGZvciBlbmFibGVfaWY/CnVzaW5nIG5hbWVzcGFjZSBzdGQ7Cgp0ZW1wbGF0ZTxjbGFzcyBUPiBzdHJ1Y3Qgc3VwcG9ydHNfaXRlcmF0aW9uCnsgCnByaXZhdGU6Cgl0eXBlZGVmIGNoYXIgeWVzWzFdOwoJdHlwZWRlZiBjaGFyIG5vWzJdOwoJdGVtcGxhdGUgPGNsYXNzIEM+IHN0YXRpYyB5ZXMmIGZvbyh0eXBlbmFtZSBDOjppdGVyYXRvciopOwoJdGVtcGxhdGUgPGNsYXNzIEM+IHN0YXRpYyBubyYgZm9vKC4uLik7CnB1YmxpYzoKCXN0YXRpYyBjb25zdGV4cHIgYm9vbCB2YWx1ZSA9IHNpemVvZihmb288VD4oMCkpID09IHNpemVvZih5ZXMpOwp9OwoKCnRlbXBsYXRlPHRlbXBsYXRlIDxjbGFzcywgY2xhc3M+IGNsYXNzIEMsIGNsYXNzIFQsIGNsYXNzIEE+CnZvaWQgRG9Tb21ldGhpbmcoQzxULEE+JiB2YWwpCnsKCVQqIHBUOwoJY291dCA8PCAiZGlkIHNvbWV0aGluZyFcbiI7Cn0KCnRlbXBsYXRlPHRlbXBsYXRlIDxjbGFzcywgY2xhc3M+IGNsYXNzIEMsIGNsYXNzIFQsIGNsYXNzIEE+CnZvaWQgRG9Tb21ldGhpbmdTbWFydGx5KAoJdHlwZW5hbWUgc3RkOjplbmFibGVfaWY8CgkJc3VwcG9ydHNfaXRlcmF0aW9uPAoJCQlDPFQsQT4KCQk+Ojp2YWx1ZQoJPjo6dHlwZSYgdmFsKQp7CglUKiBwVDsKCWNvdXQgPDwgImRpZCBzb21ldGhpbmcgc21hcnRseSFcbiI7Cn0KCnRlbXBsYXRlPHRlbXBsYXRlIDxjbGFzcywgY2xhc3M+IGNsYXNzIEMsIGNsYXNzIFQsIGNsYXNzIEEsIAogICAgdHlwZW5hbWUgPSBkZWNsdHlwZSgKICAgICAgICBkZWNsdmFsPEM8VCxBPj4oKS5zaXplKCkKICAgICAgICAsdm9pZCgpCiAgICApCj4Kdm9pZCBEb1NvbWV0aGluZ1JlYWxseVNtYXJ0bHkoQzxULEE+JiB2YWwpCnsKCVQqIHBUOwoJY291dCA8PCAiZGlkIHNvbWV0aGluZyByZWFsbHkgc21hcnRseSFcbiI7Cn0KCmludCBtYWluKCkgewoJLy8geW91ciBjb2RlIGdvZXMgaGVyZQoJdmVjdG9yPGludD4gdnsxLDIsMyw0LDV9OwoJRG9Tb21ldGhpbmcodik7Cgljb3V0IDw8ICJ2ZWN0b3I8aW50PiBzdXBwb3J0c19pdGVyYXRpb24/ICIgPDwgCgkJYm9vbGFscGhhIDw8IHN1cHBvcnRzX2l0ZXJhdGlvbjxkZWNsdHlwZSh2KT46OnZhbHVlIDw8ICIhIiA8PCBlbmRsOwoJLy9Eb1NvbWV0aGluZ1NtYXJ0bHkodik7Ly8gLSBmYWlscyEhCgkvL3RlbXBsYXRlIGFyZ3VtZW50IGRlZHVjdGlvbi9zdWJzdGl0dXRpb24gZmFpbGVkOgoJLy9jb3VsZG4ndCBkZWR1Y2UgdGVtcGxhdGUgcGFyYW1ldGVyIOKAmHRlbXBsYXRlPGNsYXNzLCBjbGFzcz4gY2xhc3MgQ+KAmSAgRG9Tb21ldGhpbmdTbWFydGx5KHYpOwoJRG9Tb21ldGhpbmdSZWFsbHlTbWFydGx5KHYpOwoJcmV0dXJuIDA7Cn0K