Inside the class declaration is a typo, change to ..
template<class T3, class T4> friend std::ostream & operator<<(std::ostream& os, const TwoThings<T3, T4> &);
And then the definition without the scope resolution operator
template<class T3, class T4> std::ostream & operator<<(std::ostream & os, const TwoThings<T3, T4> & tt)
{
std::cout<<tt.thing1<<' '<<tt.thing2;
return os;
}
When in doubt, a good place to get a 'second opinion' about a given piece of code is the Comeau's Test Drive Comeau C++ Online. It is supposed to be a very standards-compliant compiler and tends to produce quite understandable error messages.