In Why is there no base class in C++?, I quoted Stroustrup on why a common Object class for all classes is problematic in c++. In that quote there is the statement:
I think the point is that this is not "really" polymorphic (whatever that means :-).
You could write your test function like this
template void test(T& obj) { obj.f(); }
and it would still work, whether the classes have virtual functions or not.