#include <iostream>
using namespace std;
template<class T>
struct Foo{
// template<class S,typename = std::enable_if_t<std::is_convertible<S, T>::value>>
//template<class S>
template<class S,typename = std::enable_if_t<std::is_convertible<S*, T*>::value>>
Foo(S* s):_t(s){}
T * _t;
};
struct Bar{};
struct Bar2 : public Bar {};
struct NotBar{};
void do_something(Foo<Bar> f){
cout<<"In Foo do something"<<endl;
}
void do_something(std::string f){
cout<<"In string do something"<<endl;
}
int main() {
const char * string = "string";
do_something(string);
Bar2 bar2;
do_something(&bar2);
Foo<Bar> fb(&bar2);
NotBar nb;
// this SHOULD fail
//Foo<Bar> fb2(&nb);
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKdGVtcGxhdGU8Y2xhc3MgVD4Kc3RydWN0ICBGb297Ci8vIHRlbXBsYXRlPGNsYXNzIFMsdHlwZW5hbWUgPSBzdGQ6OmVuYWJsZV9pZl90PHN0ZDo6aXNfY29udmVydGlibGU8UywgVD46OnZhbHVlPj4KIC8vdGVtcGxhdGU8Y2xhc3MgUz4KIHRlbXBsYXRlPGNsYXNzIFMsdHlwZW5hbWUgPSBzdGQ6OmVuYWJsZV9pZl90PHN0ZDo6aXNfY29udmVydGlibGU8UyosIFQqPjo6dmFsdWU+PgoKRm9vKFMqIHMpOl90KHMpe30KVCAqIF90Owp9OwoKc3RydWN0IEJhcnt9OwoKc3RydWN0IEJhcjIgOiBwdWJsaWMgQmFyIHt9OwoKc3RydWN0IE5vdEJhcnt9OwoKdm9pZCBkb19zb21ldGhpbmcoRm9vPEJhcj4gZil7Cgljb3V0PDwiSW4gRm9vIGRvIHNvbWV0aGluZyI8PGVuZGw7Cn0KCnZvaWQgZG9fc29tZXRoaW5nKHN0ZDo6c3RyaW5nIGYpewoJCWNvdXQ8PCJJbiBzdHJpbmcgZG8gc29tZXRoaW5nIjw8ZW5kbDsKCn0KCmludCBtYWluKCkgewoJY29uc3QgY2hhciAqIHN0cmluZyA9ICJzdHJpbmciOwoJZG9fc29tZXRoaW5nKHN0cmluZyk7CglCYXIyIGJhcjI7Cglkb19zb21ldGhpbmcoJmJhcjIpOwoJRm9vPEJhcj4gZmIoJmJhcjIpOwoJTm90QmFyIG5iOwoJLy8gdGhpcyBTSE9VTEQgZmFpbCAKLy9Gb288QmFyPiBmYjIoJm5iKTsKCXJldHVybiAwOwp9