https://en.cppreference.com/w/cpp/language/object#Polymorphic_objects Objects of a class type that declares or inherits at least one virtual function are polymorphic objects. Within each polymorphic object, the implementation stores additional information (in every existing implementation, it is one pointer unless optimized out), which is used by virtual function calls and by the RTTI features (dynamic_cast and typeid) to determine, at run time, the type with which the object was created, regardless of the expression it is used in.
Эх, плохо я знаю RTTI. На сколько я понимаю, получается dynamic_cast нельзя использовать для того, чтобы скастить base класс без виртуальных функций к derived? Вроде правила dynamic_cast'а на cppref тоже указывают на это.
UB это и есть максимально производительное решение. То что на x86 есть SIMD инструкция которая использует переполнение с насыщением еще не значит что это так на всех платформах. Более того разработчики компилятора могут добавить преобразование неэффективного кода явно реализующего насыщение при переполнении в ту самую ассемблерную инструкцию.
Мне кажется что в большинстве случаев переполнение при конвертации float к int это логическая ошибка и с точки зрения пользователя разницы между UB и насыщением нет.
А как правильно проверит дабл на конвертируемость в integral?
В общем, в некоторых рамках эта задача могла бы быть реализована компилятором по явному запросу на генерацию, но с точки зрения С++ если задача может быть решена без компилятора не очень понятно, зачем её решать компилятором