Apart from the C++ FAQ link from leemes, C++ standard prevent it to be called, I will quote the standard.
The following says that, virtual member functions can be called within constructor/destructor, but they act as "not virtual", which you already know in the C++ FAQ.
Member functions, including virtual functions (10.3), can be called
during construction or destruction (12.6.2). When a virtual function
is called directly or indirectly from a constructor or from a
destructor, including during the construction or destruction of the
class’s non-static data members, and the object to which the call
applies is the object (call it x) under construction or destruction,
the function called is the final overrider in the constructor’s or
destructor’s class and not one overriding it in a more-derived class.
If the virtual function call uses an explicit class member access
(5.2.5) and the object expression refers to the complete object of x
or one of that object’s base class subobjects but not x or one of its
base class subobjects, the behavior is undefined.
It actually also says that, when calling virtual function from a pointer (to itself) with a type that is not direct base class of itself (in multiple inheritance), the behaviour is undefined.
Example (from standard)
struct V {
virtual void f();
virtual void g();
};
struct A : virtual V {
virtual void f();
};
struct B : virtual V {
virtual void g();
B(V*, A*);
};
struct D : A, B {
virtual void f();
virtual void g();
D() : B((A*)this, this) { }
};
B::B(V* v, A* a) {
f(); // calls V::f, not A::f
g(); // calls B::g, not D::g
v->g(); // v is base of B, the call is well-defined, calls B::g
a->f(); // undefined behavior, a’s type not a base of B
}
The above rules apply to other dynamic binding stuff, including typeid, meaning that you can't use typeid to differentiate derived class type in base constructor.
The typeid operator (5.2.8) can be used during construction or
destruction (12.6.2). When typeid is used in a constructor (including
the mem-initializer or brace-or-equal-initializer for a non-static
data member) or in a destructor, or used in a function called
(directly or indirectly) from a constructor or destructor, if the
operand of typeid refers to the object under construction or
destruction, typeid yields the std::type_info object representing the
constructor or destructor’s class. If the operand of typeid refers to
the object under construction or destruction and the static type of
the operand is neither the constructor or destructor’s class nor one
of its bases, the result of typeid is undefined.