The arrow operator has no inputs. Technically, it can return whatever you want, but it should return something that either is a pointer or can become a pointer through chained ->
operators.
The ->
operator automatically dereferences its return value before calling its argument using the built-in pointer dereference, not operator*
, so you could have the following class:
class PointerToString
{
string a;
public:
class PtPtS
{
public:
PtPtS(PointerToString &s) : r(s) {}
string* operator->()
{
std::cout << "indirect arrow";
return &*r;
}
private:
PointerToString &r;
};
PointerToString(const string &s) : a(s) {}
PtPts operator->() const
{
std::cout << "arrow dereference\n";
return *this;
}
string &operator*() const
{
std::cout << "dereference\n";
return a;
}
};
Use it like:
PointerToString ptr(string("hello"));
string::size_type size = ptr->size();
which is converted by the compiler into:
string::size_type size = (*ptr.operator->().operator->()).size();
(with as many .operator->()
as necessary to return a real pointer) and should output
arrow dereference
indirect dereference
dereference
Note, however, that you can do the following:
PointerToString::PtPtS ptr2 = ptr.operator->();
///
class PointerToString
{
string a;
public:
class PtPtS
{
public:
PtPtS(PointerToString& s) : r(s) {}
string* operator->()
{
std::cout << "indirect arrow\n";
return &*r;
}
private:
PointerToString &r;
};
PointerToString(const string &s) : a(s) {}
PtPtS operator->()
{
std::cout << "arrow dereference\n";
return *this;
}
string &operator*()
{
std::cout << "dereference\n";
return a;
}
};
PointerToString ptr(string("hello"));
string::size_type size = ptr->size();
//string::size_type size = (*ptr->()->())->size();
string::size_type size1 = (*ptr.operator->().operator->()).size();
string::size_type size2 = (ptr.operator->().operator->())->size();