Проблема в вашем коде состоит в том, что вы ожидаете полиморфизм во время выполнения, но используете только типы времени компиляции:
decltype(x)
дает вам время компиляции тип x - , поэтому
typeid(decltype(x))
относится к информации о типе среды выполнения типа времени компиляции, поэтому 4Base
в вашем примере.
Если вы хотите использоватьтип времени выполнения, используйте typeid
непосредственно для объекта следующим образом:
std::cout <<< typeid(elem).name() << '\n';
std::cout << typeid(*elem).name() << '\n';
std::cout << typeid(*elem.get()).name() << '\n';
Результат будет выглядеть следующим образом:
St10unique_ptrI4BaseSt14default_deleteIS0_EE
10DerivedFoo
10DerivedFoo
St10unique_ptrI4BaseSt14default_deleteIS0_EE
10DerivedBar
10DerivedBar
Таким же образом, std::is_same<DerivedFoo, decltype(elem)>::value
основан на выводе типа шаблона, поэтому время компиляции снова. Если вы хотите проверить это на полиморфном типе во время выполнения, вам нужно использовать следующую конструкцию:
if (dynamic_cast<DerivedFoo*>(&*elem)) {
// do something
}