Reputation: 557
In C++17, I'm trying to detect containers (maps) by checking for the presence of value_type
(mapped_type
). However, while it seems to work for unordered_set<int>
it fails for unordered_set<int*>
which I find weird. Can you tell me why and how to do it properly?
template<class N, class T = int>
struct is_container { static const bool value = false; };
template<class N>
struct is_container<N, typename N::value_type> { static const bool value = true; };
template<class N>
static constexpr bool is_container_v = is_container<remove_reference_t<N>>::value;
int main()
{
cout << is_container_v<unordered_set<int>&> << '\n';
cout << is_container_v<unordered_set<int*>&> << '\n';
}
output:
1
0
PS: I've seen this question which filters by presence of begin()
but that doesn't help telling a map
from set
.
Upvotes: 0
Views: 116
Reputation: 217850
Keeping your test, it should be
template<class N, class Enabler = void>
struct is_container { static const bool value = false; };
template<class N>
struct is_container<N, std::void_t<typename N::value_type>>
{ static const bool value = true; };
template<class N>
static constexpr bool is_container_v = is_container<remove_reference_t<N>>::value;
As, with your version
is_container_v<unordered_set<int*>&>
is is_container<unordered_set<int*>>
and with default: is_container<unordered_set<int*>, int>
whereas you specialize for is_container<unordered_set<int*>, int*>
...
Upvotes: 3