#include <iostream>
#include <vector>
#include <string>
template <typename, typename>
struct foo_Impl;
template <typename T>
class A
{
public:
template <typename U>
void foo() const { foo_Impl<T, U>(*this); }
private:
template <typename, typename>
friend struct foo_Impl;
void print(const std::string& text) const
{
std::cout << this << ": " << text <<std::endl;
}
};
template <typename T, typename>
struct foo_Impl
{
foo_Impl(const A<T>& owner) { owner.print("general implementation"); }
};
template <typename T>
struct foo_Impl<T, double>
{
foo_Impl(const A<T>& owner) { owner.print("specialization for double"); }
};
template <typename T, typename U>
struct foo_Impl<T, std::vector<U>>
{
foo_Impl(const A<T>& owner) { owner.print("specialization for vectors of all types"); }
};
int main() {
A<int> a;
a.foo<int>();
a.foo<double>();
a.foo<std::vector<bool>>();
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8c3RyaW5nPgoKdGVtcGxhdGUgPHR5cGVuYW1lLCB0eXBlbmFtZT4JCnN0cnVjdCBmb29fSW1wbDsKCnRlbXBsYXRlIDx0eXBlbmFtZSBUPgpjbGFzcyBBCnsKcHVibGljOgogIHRlbXBsYXRlIDx0eXBlbmFtZSBVPgogIHZvaWQgZm9vKCkgY29uc3QgeyBmb29fSW1wbDxULCBVPigqdGhpcyk7IH0KCnByaXZhdGU6CiAgdGVtcGxhdGUgPHR5cGVuYW1lLCB0eXBlbmFtZT4JCiAgZnJpZW5kIHN0cnVjdCBmb29fSW1wbDsKCiAgdm9pZCBwcmludChjb25zdCBzdGQ6OnN0cmluZyYgdGV4dCkgY29uc3QKICB7CiAgCXN0ZDo6Y291dCA8PCB0aGlzIDw8ICI6ICIgPDwgdGV4dCA8PHN0ZDo6ZW5kbDsKICB9Cn07Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWU+CQpzdHJ1Y3QgZm9vX0ltcGwKewogIGZvb19JbXBsKGNvbnN0IEE8VD4mIG93bmVyKSB7IG93bmVyLnByaW50KCJnZW5lcmFsIGltcGxlbWVudGF0aW9uIik7IH0KCQp9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CnN0cnVjdCBmb29fSW1wbDxULCBkb3VibGU+CnsKICBmb29fSW1wbChjb25zdCBBPFQ+JiBvd25lcikgeyBvd25lci5wcmludCgic3BlY2lhbGl6YXRpb24gZm9yIGRvdWJsZSIpOyB9Cn07Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUgVT4Kc3RydWN0IGZvb19JbXBsPFQsIHN0ZDo6dmVjdG9yPFU+Pgp7CiAgZm9vX0ltcGwoY29uc3QgQTxUPiYgb3duZXIpIHsgb3duZXIucHJpbnQoInNwZWNpYWxpemF0aW9uIGZvciB2ZWN0b3JzIG9mIGFsbCB0eXBlcyIpOyB9Cn07CgppbnQgbWFpbigpIHsKCiAgQTxpbnQ+IGE7CgogIGEuZm9vPGludD4oKTsKICBhLmZvbzxkb3VibGU+KCk7CiAgYS5mb288c3RkOjp2ZWN0b3I8Ym9vbD4+KCk7Cn0=