Because you declare a static member variable but you never define it. This line:
static Inner inner;
does NOT allocate space for an object of class Outer::Inner. It only says to the compiler "I promise that in some source file, I will define Outer<T>::inner.
One issue here is that you have templatized this class; static members and templates mix poorly because of the convoluted way you must both declare and later define the static member. The correct code is:
Code:
template <class T>
class Outer {
class Inner
{
public:
void f() {}
};
public:
static Inner inner;
};
int main()
{
Outer<int>::inner.f();
return 0;
}
Outer<int>::Inner Outer<int>::inner;
The bad news is that you need to explicitly allocate that static variable, and you can't templatize it. So you should try to do without a static data member if you can possibly avoid it.
It's the same reason that:
Code:
class C{
public:
static int c;
};
int main(){
C::c = 5; // causes a link error, C::c doesn't exist.
}
is a linker error (you declare a static int to exist but don't actually make it happen), while:
Code:
class C{
public:
static int c;
};
int C::c;
int main(){
C::c = 5;
}
is OK.