My guess is that this is a g++ bug, that is somehow related to an old C++98 restriction on the use of local classes as template parameters
// C++98 Standard
14.3.1/2: A local type, a type with no linkage, an unnamed type or a type compounded from any of these types shall not be used as a template-argument for a template type-parameter.
In C++11, this restriction has been lifted. As you note, Visual Studio compiles this correctly, and so does Clang. As a work-around, adding the definition of the abstract function works with g++
template<typename T>
void Outer<T>::InnerBase::foo(T const&) {};
I think you should submit a bug report to g++.