gpt4 book ai didi

c++ - 在编译时使整数序列唯一

转载 作者:行者123 更新时间:2023-12-04 11:03:14 34 4
gpt4 key购买 nike

假设我有:

template<int... N>
class seq
{
};

template<int... N>
struct uniq{
using type = seq<N...>;
};
我需要以某种方式使序列独一无二,这样
std::is_same_v<uniq<1,2,2,2,3,3,3>::type, seq<1, 2, 3>>; 
最终是真的。换句话说,使序列唯一,然后创建一个序列。
有没有办法在编译时实现这一点?

最佳答案

使用 std使用 <type_traits> 从标准库中,您可以像这样实现自己的:

#include <type_traits>

namespace detail
{
template<class, auto... Ns>
struct uniq_impl;
template<template<auto...> class T, auto... Ms, auto N, auto... Ns>
struct uniq_impl<T<Ms...>, N, Ns...> : std::conditional_t<
(... || (N == Ms)),
uniq_impl<T<Ms...>, Ns...>,
uniq_impl<T<Ms..., N>, Ns...>>
{
};
template<template<auto...> class T, auto... Ms>
struct uniq_impl<T<Ms...>>
{
using type = T<Ms...>;
};
} // namespace detail

template<int... Ns>
class seq
{
};

template<int... Ns>
using uniq = detail::uniq_impl<seq<>, Ns...>;

static_assert(std::is_same_v<typename uniq<1,2,2,2,3,3,3>::type, seq<1, 2, 3>>);
uniq_impl从一个空的 seq<> 开始工作和 auto... Ns 的参数包,然后使用模板特化一次一个地取出参数包的前面
template<template<auto...> class T, auto... Ms, auto N, auto... Ns>
struct uniq_impl<T<Ms...>, N, Ns...> : std::conditional_t<
(... || (N == Ms)),
uniq_impl<T<Ms...>, Ns...>,
uniq_impl<T<Ms..., N>, Ns...>>
{
};
它检查是否 Nauto... Ms 的集合中使用 fold expression并决定是否推送 N转至 Ms或使用 std::conditional_t 丢弃它.一次 auto... Ns为空,然后使用特化
template<template<auto...> class T, auto... Ms>
struct uniq_impl<T<Ms...>>
{
using type = T<Ms...>;
};
标记生成的唯一值容器。在 godbolt.org 上试用: Demo .
使用 boost::mp11others have pointed out ,您可以将算法委托(delegate)给 boost::mp11::mp_unique , 但因为 it works for types and not values ,您需要将值包装和解包到 std::integral_constant 为了使用这种方法:
#include <boost/mp11/algorithm.hpp>

namespace detail
{
template<template<auto...> class T, auto... Ns>
class uniq_impl
{
static boost::mp11::mp_list<std::integral_constant<decltype(Ns), Ns>...> types();

template <class L>
static boost::mp11::mp_unique<L> transform(L);

template<class... Ts, auto... Ms>
static T<Ms...> values(boost::mp11::mp_list<std::integral_constant<Ts, Ms>...>);

public:
using type = decltype(values(transform(types())));
};
} // namespace detail

template<int... Ns>
class seq
{
};

template<int... Ns>
using uniq = detail::uniq_impl<seq, Ns...>;

static_assert(std::is_same_v<typename uniq<1,2,2,2,3,3,3>::type, seq<1, 2, 3>>);
在 godbolt.org 上试用: Demo .

关于c++ - 在编译时使整数序列唯一,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66335672/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com