Я немного запутался здесь и надеюсь получить комментарии к этому ответу, объясняющие, чего мне не хватает.
Конечно, если вы хотите выяснить, является ли класс полиморфным, все, что вам нужно сделать, это спросить, поддерживает ли он dynamic_cast
, не так ли?
template<class T, class> struct is_polymorphic_impl : false_type {};
template<class T> struct is_polymorphic_impl
<T, decltype(dynamic_cast<void*>(declval<T*>()))> : true_type {};
template<class T> struct is_polymorphic :
is_polymorphic_impl<remove_cv_t<T>, void*> {};
Кто-нибудь может указать на недостаток в этой реализации? Я предполагаю, что он должен быть или должен был быть в какой-то момент в прошлом, потому что документация Boost продолжает утверждать, что is_polymorphic
"не может быть реализовано переносимым образом на языке C ++".
Но "переносимо" - это своего рода ласка слова, верно? Возможно, они просто намекают на то, что MSVC не поддерживает выражение-SFINAE, или некоторые диалекты, такие как Embedded C ++, не поддерживают dynamic_cast
. Возможно, когда они говорят «язык C ++», они имеют в виду «подмножество наименьшего общего знаменателя языка C ++». Но у меня есть ноющее подозрение, что, возможно, они имеют в виду то, что говорят, и Я тот, кто что-то упустил.
Подход typeid
в ОП (с поправками, внесенными более поздним ответом, чтобы использовать lvalue, а не rvalue) также выглядит хорошо, но, конечно, это не constexpr, и он требует фактического построения T
, что может быть дорого. Так что этот dynamic_cast
подход кажется лучше ... если только он по какой-то причине не работает. Мысли