b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

【c语言在vc++6.0中编写界面程序】(2)

电脑杂谈  发布时间:2019-11-11 03:03:39  来源:网络整理
template <class array="">constexpr auto count_nonzeros(Array a) noexcept {    std::size_t count = 0;    for (std::size_t i = 0; i < Array::size() && a.data[i]; ++i)        ++ count;    return count;}</class>

由于字段是按次序保存到 array 中的,所以在元素值为0时的 count 就是有效的元素个数。接下来我们来说说 detect _ fields _ count _ and _ type _ ids 的实现,这个 constexpr 函数将结构体中的数组类型 id 保存到 array 的 data 中。

detect_fields_count_and_type_ids<t>(types.data, std::make_index_sequence<sizeof(t)>{});</sizeof(t)></t>

detect _ fields _ count _ and _ type _ ids 的第一个参数为定长数组 array <std::size _ t, sizeof(T)> 的 data,第二个参数是一个 std::index _ sequence 整形序列。detect _ fields _ count _ and _ type _ ids 具体实现代码如下:

template <class t,="" std::size_t="" i0,="" std::size_t...="" i="">constexpr auto detect_fields_count_and_type_ids(std::size_t* types, std::index_sequence<i0, i...="">) noexcept-> decltype( type_to_array_of_type_ids<t, i0,="" i...="">(types) ){    return type_to_array_of_type_ids<t, i0,="" i...="">(types);}template <class t,="" std::size_t...="" i="">constexpr T detect_fields_count_and_type_ids(std::size_t* types, std::index_sequence<i...>) noexcept {    return detect_fields_count_and_type_ids<t>(types, std::make_index_sequence<sizeof...(i) -="" 1="">{});}template <class t="">constexpr T detect_fields_count_and_type_ids(std::size_t*, std::index_sequence<>) noexcept {    static_assert(!!sizeof(T), "Failed for unknown reason");    return T{};}</class></sizeof...(i)></t></i...></class></t,></t,></i0,></class>

上面的代码是为了将 index _ sequence 展开为 0,1,2..., sizeof(T) 序列,得到这个序列以后,再读取 type _ to _ array _ of _ type _ ids 函数实现结构体中的字段类别 id 保存到 array 中。

在讲 type _ to _ array _ of _ type _ ids 函数之前我们先看一下辅助结构体 ubiq。保存 pod 字段类别 id 实际上是由辅助结构体 ubiq 实现的,它的实现如下:

template <std::size_t i="">struct ubiq {    std::size_t* ref_;    template <class type="">    constexpr operator Type() const noexcept {        ref_[I] = type_to_id(identity<type>{});        return Type{};    }};</type></class></std::size_t>

这个结构体比较特殊,我们先把它简化一下。

struct ubiq {    template <class type="">    constexpr operator Type() const {        return Type{};    };};</class>

c语言贪吃蛇程序_c语言windows编程视频教程_vc6.0怎么写c语言

这个结构体的特殊之处在于它可以拿来构造任意 pod 类型,比如 int、char、double 等类别。

int i = ubiq{};double d = ubiq{};char c = ubiq{};

因为 ubiq 构造函数所必须的类别由编译器自动判断起来,所以它能构造任意 pod 类型。通过 ubiq 结构体获取了应该构造的类型以后,我们还必须将这个类别转换为 id 按次序保存到定长数组中。

template <std::size_t i="">struct ubiq {    std::size_t* ref_;    template <class type="">    constexpr operator Type() const noexcept {        ref_[I] = type_to_id(identity<type>{});        return Type{};    }};</type></class></std::size_t>

上面的代码中先将编译器推导出来的类别转换为 id,然后保存到链表数组为 I 的位置。

再回头看 type _ to _ array _ of _ type _ ids 函数。

template <class t,="" std::size_t...="" i="">constexpr auto type_to_array_of_type_ids(std::size_t* types) noexcept -> decltype(T{ ubiq<i>{types}... }) {    return T{ ubiq<i>{types}... };}</i></i></class>

type _ to _ array _ of _ type _ ids 有两个模版参数,第一个 T 是 pod 结构体的类别,第二个 size _ t...为0到 sizeof(T) 的整形序列,函数的入参为 size _ t*,它实际上是 array<std::size_t, sizeof(T)> 的 data,用来保存 pod 字段类别 id。

保存字段类别的关键代码是这一行:T{ ubiq〈I〉{types}... },这里利用了 pod 类型的构造函数,通过 initializer _ list 构造,编译器会将 T 的字段类别归纳出来,并通过 ubiq 将字段类别转换为 id 保存到变量中。这个就是 magic _ get 中的 magic。

将 pod 结构体字段 id 保存到变量中以后,接下来就应该将变量中的 id 列表转换为 tuple 了。

pod 字段 id 序列转化为 tuple 的详细做法分为两步:

下面是详细的实现代码:

template <std::size_t i,="" class="" t,="" std::size_t="" n="">constexpr const T& get(const array<t,n>& a) noexcept {    return a.data[I];}template <class t,="" std::size_t...="" i="">constexpr auto array_of_type_ids_to_index_sequence(std::index_sequence<i...>) noexcept {    constexpr auto a = array_of_type_ids<t>();    return std::index_sequence< get<i>(a)...>{};}</i></t></i...></class></t,n></std::size_t>

get 是返回函数中某个键值位置的元素值,即类型 id,返回的 id 放入 std::index _ sequence 中,接着就是通过 index _ sequence 将 index _ sequence 中的 id 转换为 type,组成一个 tuple。

template <std::size_t... i="">constexpr auto as_tuple_impl(std::index_sequence<i...>) noexcept {    return std::tuple< decltype( id_to_type(std::integral_constant<std::size_t, i="">{}) )... >{};}template <class t="">constexpr auto as_tuple() noexcept {    static_assert(std::is_pod<t>::value, "Not applyable");    constexpr auto res = as_tuple_impl(            array_of_type_ids_to_index_sequence<t>(                    std::make_index_sequence< decltype(array_of_type_ids<t>())::size() >()            )    );    static_assert(sizeof(res) == sizeof(T), "sizes check failed");    static_assert(            std::alignment_of<decltype(res)>::value == std::alignment_of<t>::value,            "alignment check failed"    );    return res;}</t></decltype(res)></t></t></t></class></std::size_t,></i...></std::size_t...>


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-129594-2.html

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    • 周定王
      周定王

      台湾执政者也是明白之人

    • 曹海莹
      曹海莹

      送项目拉动它们的经济

    每日福利
    热点图片
    拼命载入中...