Perché i puntatori non sono oggetti, pertanto il tuo operatore di confronto passa in secondo piano rispetto a quello naturale, implicito tra raw pointer.
Se utilizzi shared_pointer la faccenda cambia, ma non molto. Gli shared_pointer definiscono un loro operatore di confronto, ma ciò che fa questo operatore è un confronto tra i raw pointer memorizzati. Se il tuo scopo è confrontare due CMaterial devi dereferenziare i puntatori (meglio se di classe shared_ptr) all'interno dell'operatore < .
codice:bool operator <(const shared_ptr<Cmateria>l& mat1, const shared_ptr<Cmaterial>& mat2) { return ( *mat1 < *mat2); }