Why can operator-> be overloaded manually?
Wouldn't it make sense if p->m
was just syntactic sugar for (*p).m
? Essentially, every operator->
that I have ever written could have been implemented as follows:
Foo::Foo* operator->()
{
开发者_StackOverflow社区 return &**this;
}
Is there any case where I would want p->m
to mean something else than (*p).m
?
operator->()
has the bizarre distinction of implicitly being invoked repeatedly while the return type allows it. The clearest way to show this is with code:
struct X {
int foo;
};
struct Y {
X x;
X* operator->() { return &x; }
};
struct Z {
Y y;
Y& operator->() { return y; }
};
Z z;
z->foo = 42; // Works! Calls both!
I recall an occasion when this behaviour was necessary to enable an object to behave as a proxy for another object in a smart-pointer-like context, though I can't remember the details. What I do remember is that I could only get the behaviour to work as I intended using the a->b
syntax, by using this strange special case; I could not find a way to get (*a).b
to work similarly.
Not sure that this answers your question; really I'm saying, "Good question, but it's even weirder than that!"
One use case might be when you're creating a DSL inside C++, along the lines of Boost Karma (although it does not seem to overload ->
in their library), where you completely change the meaning of the traditional C++ operators. Whether that's a good idea is certainly up to debate.
Regular pointers offer p->m
and (*p).m
, with p->m
being by far the more common. If you only allowed overloading one of them, then it would be inconsistent with the default type. As for why not let the compiler rewrite it, the simple answer is because sometimes, you don't want operator-> to return T*, where operator* returns T&. Allowing them to be overloaded separately allows combinations that you can't necessarily think of. But it would be silly to disallow it, just because we can't currently think of any reason to change it. Much like, you could have an int128 class and overload operator+= to mean exponentiation instead, if you so wanted.
You might want to do some other operations, like incrementing a variable (access counting) or even some safety checks etc. On the other hand, i had never need to overload the operator-> ...
I think it's used for shared_ptr<> in boost (for example). That makes them "look" like normal pointers, although they're special pointers (reference counting afaik).
精彩评论