template <class T>
struct Base{};

template <class T>
struct B;

template <class T>
struct A: public Base<T>
{
	operator B<T>();
};

template <typename T>
B<T> operator*(const Base<T>& s1, const Base<T>& s2){ return B<T>(); }

template <class T>
struct B: public Base<T>
{
	A<T> operator[](const B&) { return A<T>(); }
	friend B operator* <T>(const Base<T>&, const Base<T>&);
};

template <class T> A<T>::operator B<T>(){ return B<T>(); }

int main()
{
	B<int> s1, s2, s3;
	s1[s2] * s3;
	s1[s2] * s3;
	s3 * s1[s2];
	s1[s2] * s1[s2];
	s3 * s3;
}