I'm working with some classes that may have a nested type defined. Whenever this nested type is not defined I pretend like this nested type is void. For example, here is the code that should work:
struct HasNestedTypeDefined {
using Nested = int;
};
struct VoidNestedTypeDefined {
using Nested = void;
};
struct NoNestedTypeDefined {
};
static_assert(!std::is_same_v<reveal_nested_type< HasNestedTypeDefined>::type, void>);
static_assert( std::is_same_v<reveal_nested_type< HasNestedTypeDefined>::type, int>);
static_assert( std::is_same_v<reveal_nested_type<VoidNestedTypeDefined>::type, void>);
static_assert(!std::is_same_v<reveal_nested_type<VoidNestedTypeDefined>::type, int>);
static_assert( std::is_same_v<reveal_nested_type< NoNestedTypeDefined>::type, void>);
static_assert(!std::is_same_v<reveal_nested_type< NoNestedTypeDefined>::type, int>);
So far I've got this working:
template<typename T, typename R = void>
struct enable_if_type {
using type = R;
};
template<typename T, typename = void>
struct reveal_nested_type {
using type = void;
};
template<typename T>
struct reveal_nested_type<T, typename enable_if_type<typename T::Nested>::type> {
using type = typename T::Nested;
};
I thought that SFINAE should work even without using enable_if_type, like that:
template<typename T, typename = void>
struct reveal_nested_type {
using type = void;
};
template<typename T>
struct reveal_nested_type<T, typename T::Nested> {
using type = typename T::Nested;
};
but the partial specialization is never used in this case, even if the typename T::Nested is defined. Why does SFINAE ignore it? The follow up question: is there a more idiomatic way to implement the same?