Этот код основан на убеждении, что в стандарте указано dynamic_cast
как-то так:
namespace std {
template <typename Dst, typename Src>
Dst* dynamic_cast(Src* );
}
Но хотя четыре приведения C ++ могут выглядеть как вызовы шаблонов функций, онина самом деле часть основного языка.Это ключевые слова, они не ограничены областью, и хотя они принимают одну вещь, которая выглядит как параметр типа шаблона, на самом деле это не так.
Так что &std::dynamic_cast<B, A>
не имеет никакого смысла.std::dynamic_cast
вообще нет, dynamic_cast
принимает только один аргумент типа, и вы не можете иметь "частичное" динамическое приведение - выражение dynamic_cast<T>(v)
, вы не можете просто иметь dynamic_cast<T>
само по себе.
Предполагая, что std::dynamic_cast
является просто опечаткой для std::dynamic_pointer_cast
, с вашим кодом есть еще две проблемы:
- Вы не можете
dynamic_cast
и A*
до B*
.Вы можете upcast неполиморфные объекты / указатели, но вы не можете downcast их.Так что это неправильно. Если вы сделаете A
полиморфным, проблема станет более понятной, если вы немного уменьшите его и сделаете базовый вариант ObjFirst
неполным вместоempty:
template <typename T>
struct ObjFirst;
template <typename T>
struct ObjFirst<void (*)(T)> {};
template <typename T, typename R>
struct ObjFirst<R (*)(T)> {} ;
struct B { };
struct D : B { };
int main()
{
ObjFirst<decltype(&std::dynamic_pointer_cast<B,D>)> n;
}
Это не скомпилируется с ошибкой:
foo.cxx: In function ‘int main()’:
foo.cxx:18:57: error: aggregate ‘ObjFirst<std::shared_ptr<B> (*)(const std::shared_ptr<D>&) noexcept> n’ has incomplete type and cannot be defined
ObjFirst<decltype(&std::dynamic_pointer_cast<B,D>)> n;
^
Что должно прояснить, в чем проблема.У вас есть специализации для void(*)(T)
и R(*)(T)
, но std::dynamic_pointer_cast
тоже не совпадает, потому что noexcept
теперь является частью системы типов.