c++ 检测Map实现是否支持不完整类型

myzjeezk  于 2022-12-15  发布在  其他
关注(0)|答案(1)|浏览(146)

我想看看map实现是否支持不完整类型,因为libc似乎支持它们,但stdlibc不支持。
我在这里尝试了SFINAE,但它给出了一个编译错误:

template<template<typename, typename, typename...> typename MapType, typename = void>
struct allows_incomplete : std::false_type {};

struct incomplete_type;
template<template<typename, typename, typename...> typename MapType>
struct allows_incomplete<MapType, std::void_t<decltype(MapType<std::string_view, incomplete_type>{})>> : std::true_type {};

static_assert(allows_incomplete<std::map>::value);
static_assert(!allows_incomplete<std::unordered_map>::value);
wb1gzix0

wb1gzix01#

要检查map是否支持不完整类型,您需要确定这样的map本身是否是完整类型。完整类型和不完整类型之间的唯一区别是不可能获得不完整类型的大小,即不可能获得不完整类型的sizeof()。因此,我们可以基于此构造不完整类型的检测器。类似于以下内容:

#include <type_traits>
#include <map>
#include <unordered_map>
#include <iostream>

namespace detail {
    template<int N>
    struct test {using type = void;};
}

template<typename T, typename = void>
struct is_complete : std::false_type {};

template<typename T>
struct is_complete<T, typename detail::test<sizeof(T)>::type> : std::true_type {};

struct incomplete_type;
struct complete_type {};

template<template<typename, typename, typename...> typename MapType>
using allows_incomplete = is_complete<MapType<int, incomplete_type>>;

int main()
{
    std::cout << std::boolalpha << is_complete<incomplete_type>::value << std::endl;
    std::cout << std::boolalpha << is_complete<complete_type>::value << std::endl;
    std::cout << std::boolalpha << is_complete<std::map<int, incomplete_type>>::value << std::endl;
    std::cout << std::boolalpha << is_complete<std::unordered_map<int, incomplete_type>>::value << std::endl;
    std::cout << std::boolalpha << allows_incomplete<std::map>::value << std::endl;
    std::cout << std::boolalpha << allows_incomplete<std::unordered_map>::value << std::endl;
}

顺便说一句,GCC 11.3似乎有bug,因为即使是std::is_constructible<std::unordered_map<int, incomplete_type>>::value也会给出同样的错误,这绝对是不正确的。

相关问题