template <typename T>
class smart_ptr
{
public:
// ... removed other member functions for simplicity
T* get() { return ptr; }
template <typename U>
auto operator [](U u) const -> decltype((*get())[u])
{
return (*get())[u];
}
template <typename U>
auto operator [](U u) -> decltype((*get())[u])
{
return (*get())[u];
}
/*
// These work fine:
template <typename U>
int operator [](U u)
{
return (*get())[u];
}
template <typename U>
int& operator [](U u)
{
return (*get())[u];
}
*/
private:
T* ptr;
};
struct Test
{
};
struct Test2
{
int& operator [](int i) { return m_Val; }
int operator [](int i) const { return m_Val; }
int m_Val;
};
int main()
{
smart_ptr<Test> p1;
smart_ptr<Test2> p2;
p2[0] = 1;
}
dGVtcGxhdGUgPHR5cGVuYW1lIFQ+CmNsYXNzIHNtYXJ0X3B0cgp7CnB1YmxpYzoKICAgIC8vIC4uLiByZW1vdmVkIG90aGVyIG1lbWJlciBmdW5jdGlvbnMgZm9yIHNpbXBsaWNpdHkKICAgIFQqIGdldCgpIHsgcmV0dXJuIHB0cjsgfQoKICAgIHRlbXBsYXRlIDx0eXBlbmFtZSBVPgogICAgYXV0byBvcGVyYXRvciBbXShVIHUpIGNvbnN0IC0+IGRlY2x0eXBlKCgqZ2V0KCkpW3VdKQogICAgewogICAgICAgIHJldHVybiAoKmdldCgpKVt1XTsKICAgIH0KCiAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVT4KICAgIGF1dG8gb3BlcmF0b3IgW10oVSB1KSAtPiBkZWNsdHlwZSgoKmdldCgpKVt1XSkKICAgIHsKICAgICAgICByZXR1cm4gKCpnZXQoKSlbdV07CiAgICB9CgovKgogICAgLy8gVGhlc2Ugd29yayBmaW5lOgoKICAgIHRlbXBsYXRlIDx0eXBlbmFtZSBVPgogICAgaW50IG9wZXJhdG9yIFtdKFUgdSkKICAgIHsKICAgICAgICByZXR1cm4gKCpnZXQoKSlbdV07CiAgICB9CgogICAgdGVtcGxhdGUgPHR5cGVuYW1lIFU+CiAgICBpbnQmIG9wZXJhdG9yIFtdKFUgdSkKICAgIHsKICAgICAgICByZXR1cm4gKCpnZXQoKSlbdV07CiAgICB9CiovCnByaXZhdGU6CiAgICBUKiBwdHI7Cn07CgpzdHJ1Y3QgVGVzdAp7Cn07CgpzdHJ1Y3QgVGVzdDIKewogICAgaW50JiBvcGVyYXRvciBbXShpbnQgaSkgeyByZXR1cm4gbV9WYWw7IH0KICAgIGludCBvcGVyYXRvciBbXShpbnQgaSkgY29uc3QgeyByZXR1cm4gbV9WYWw7IH0KCiAgICBpbnQgbV9WYWw7Cn07CgppbnQgbWFpbigpCnsKICAgIHNtYXJ0X3B0cjxUZXN0PiBwMTsKICAgIHNtYXJ0X3B0cjxUZXN0Mj4gcDI7CiAgICBwMlswXSA9IDE7Cn0=