通过 SFINAE 对容器进行 C++ 测试
C++ test for containers via SFINAE
在 C++17 中,我试图通过检查是否存在 value_type
(mapped_type
) 来检测容器(映射)。然而,虽然它似乎对 unordered_set<int>
有效,但对 unordered_set<int*>
无效,我觉得这很奇怪。你能告诉我为什么以及如何正确地做到这一点吗?
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';
}
输出:
1
0
PS:我看到 会根据 begin()
的存在进行过滤,但这无助于从 set
中分辨出 map
。
保持你的测试,它应该是
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;
与您的版本一样
is_container_v<unordered_set<int*>&>
是 is_container<unordered_set<int*>>
,默认情况下:is_container<unordered_set<int*>, int>
而您专攻 is_container<unordered_set<int*>, int*>
...
在 C++17 中,我试图通过检查是否存在 value_type
(mapped_type
) 来检测容器(映射)。然而,虽然它似乎对 unordered_set<int>
有效,但对 unordered_set<int*>
无效,我觉得这很奇怪。你能告诉我为什么以及如何正确地做到这一点吗?
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';
}
输出:
1
0
PS:我看到 begin()
的存在进行过滤,但这无助于从 set
中分辨出 map
。
保持你的测试,它应该是
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;
与您的版本一样
is_container_v<unordered_set<int*>&>
是 is_container<unordered_set<int*>>
,默认情况下:is_container<unordered_set<int*>, int>
而您专攻 is_container<unordered_set<int*>, int*>
...