Это можно сделать, используя тот же метод, что и при обнаружении элементов данных. Вместо использования элемента данных просто используйте тип элемента и void_t
:
template <typename T, typename = void>
struct hasSomeType : std::false_type {};
template <typename T>
struct hasSomeType<T, std::void_t<typename T::member_type>> : std::true_type {};
В качестве альтернативы вы можете использовать идиому обнаружения :
template<typename T>
using member_type_t = typename T::member_type;
Вы можно поместить туда любое выражение, используя decltype
.
Затем используйте псевдоним для выполнения обнаружения:
if constexpr (is_detected<member_type_t, Test>) {
// ...
}
Конечно, в C ++ 20 все это становится одним лайнером :
// requires a type
if constexpr (requires(Test) { typename Test::member_type; }) {
}
// requires a member
if constexpr (requires(Test t) { t.member; }) {
}
Живой пример