The ARM says that the return type of operator-> must either be a pointer to a class or a type (or reference to a type) that has operator-> defined. The return type is checked at the point of declaration.

	struct A
	{
		int m;
	};
	class B
	{
	public:
		A*	operator->();	// fine
	};
	class C
	{
	public:
		B&	operator->();	// fine
	};
	class D
	{
	public:
		int	operator->();	// ill-formed
		A	operator->();	// ill-formed
	};

First of all, the committee decided that this was too restrictive for templates:

	template<typename T>
	class Handle
	{
	public:
		T*	operator->();
	};
	Handle<int>	hi;	// ill-formed because it
	           	   	// declares int* operator->();

so the restriction was relaxed for template class members. I complained this made a special case which was unnecessary given that you can write:

	hi.operator->();

and that other parts of the language performed checks on use rather than on declaration (e.g., ambiguity). So I proposed that the restrictions were removed completely, leaving only the requirement that the builtin -> has a pointer to a class as its left hand operand.

	class E
	{
	public:
		int	operator->();	// fine now!
	};

An additional part of my proposal was to add operator-> to the iterators in the standard library. This was taken up by Bruce Eckel and Beman Dawes who worked on the proposal and brought it to the full committee where it was accepted in July '95.