c++ - 从编译时 vector 中删除相邻重复项的元程序

标签 c++ templates metaprogramming template-meta-programming

我一直在尝试编写一个元函数来从定义为的编译时 vector 中删除相邻的重复项

template <int...>
struct Vector;

例如。如果输入是:

Vector<1, 2, 2, 3, 3, 4, 5, 5>

输出应该是:

Vector<1, 2, 3, 4, 5>

但是如果输入是:

Vector<1, 2, 2, 3, 4, 4, 1, 5>

输出应该是:

Vector<1, 2, 3, 4, 1, 5>

如果 vector 未排序,则预计会出现重复。

我尝试了以下代码:

#include <iostream>
#include <type_traits>

template <int...>
struct Vector;

template <int I, int... L>
struct Vector<I, L...> {
    int First = I;
};

template <int Elem, typename Vector>
struct Append {
    using type = Vector;
};

template <template<int...> class Vector, int Elem, int... VecArgs>
struct Append<Elem, Vector<VecArgs...>> {
    using type = Vector<Elem, VecArgs...>;
};

template <typename Vector>
struct uniq;

template <template<int...> class Vector, int First, int... Last>
struct uniq<Vector<First, First, Last...>> {
    using type = typename uniq<Vector<Last...>>::type;
};

template <template<int...> class Vector, int First, int... Last>
struct uniq<Vector<First, Last...>> {
    using type = typename Append<First, uniq<Vector<Last...>>::type>::type;
};

template <template<int> typename Vector, int I>
struct uniq<Vector<I>> {
    using type = Vector<I>;
};


int solution(int X) {
    static_assert(std::is_same<uniq<Vector<1, 2, 2, 3, 4, 4>>::type, Vector<1, 2, 3, 4>>::value);
    static_assert(std::is_same<uniq<Vector<1>>::type, uniq<Vector<1>>::type>::value);
    //static_assert(std::is_same<Vector<1, 2, 3>, Append<1, Vector<2, 3>>::type>::value);
    return X;
}

int main() {
    solution(1);
}

我正在尝试递归删除重复项。如果前两个元素相等,则丢弃第一个元素并对其余元素调用 uniq。否则取第一个元素并为剩余元素追加 uniq。

但是这段代码不起作用。产生以下错误。

meta.cpp:32:65: error: type/value mismatch at argument 2 in template parameter list for ‘template<int Elem, class Vector> struct Append’
  using type = typename Append<First, uniq<Vector<Last...>>::type>::type;
                                                                 ^
meta.cpp:32:65: note:   expected a type, got ‘uniq<Vector<Last ...> >::type’
meta.cpp: In function ‘int solution(int)’:
meta.cpp:42:61: error: ‘type’ is not a member of ‘uniq<Vector<1, 2, 2, 3, 4, 4> >’
  static_assert(std::is_same<uniq<Vector<1, 2, 2, 3, 4, 4>>::type, Vector<1, 2, 3, 4>>::value);
                                                             ^~~~
meta.cpp:42:61: error: ‘type’ is not a member of ‘uniq<Vector<1, 2, 2, 3, 4, 4> >’
meta.cpp:42:84: error: template argument 1 is invalid
  static_assert(std::is_same<uniq<Vector<1, 2, 2, 3, 4, 4>>::type, Vector<1, 2, 3, 4>>::value);
                                                                                    ^~
meta.cpp:43:46: error: ‘type’ is not a member of ‘uniq<Vector<1> >’
  static_assert(std::is_same<uniq<Vector<1>>::type, uniq<Vector<1>>::type>::value);
                                              ^~~~
meta.cpp:43:46: error: ‘type’ is not a member of ‘uniq<Vector<1> >’
meta.cpp:43:69: error: ‘type’ is not a member of ‘uniq<Vector<1> >’
  static_assert(std::is_same<uniq<Vector<1>>::type, uniq<Vector<1>>::type>::value);
                                                                     ^~~~
meta.cpp:43:69: error: ‘type’ is not a member of ‘uniq<Vector<1> >’
meta.cpp:43:73: error: template argument 1 is invalid
  static_assert(std::is_same<uniq<Vector<1>>::type, uniq<Vector<1>>::type>::value);
                                                                         ^
meta.cpp:43:73: error: template argument 2 is invalid

我尝试了很多东西。例如。 std::conditional 但似乎无法弄清楚为什么没有任何效果。我是模板元编程的新手,在互联网上找不到很多示例。

如有任何帮助,我们将不胜感激。非常感谢。

最佳答案

  1. 您不需要模板模板参数template<int...> class Vector .

  2. 当前两个元素相等时,应保留其中一个:

    template <template<int...> class Vector, int First, int... Last>
    struct uniq<Vector<First, First, Last...>> {
        using type = typename uniq<Vector<First, Last...>>::type;
        //                                ^^^^^
    };
    
  3. 你也应该处理空包。最简单的方法就是添加 ... :

    template<int... I>
    struct uniq<Vector<I...>> {
        using type = Vector<I...>;
    };
    

在这些更改之后,您的代码将编译并且静态断言将通过。 Demo .

为了完整起见,这里是更正后的代码:

template<int Elem, typename Vector>
struct Append;

template<int Elem, int... VecArgs>
struct Append<Elem, Vector<VecArgs...>> {
    using type = Vector<Elem, VecArgs...>;
};

template<typename Vector>
struct uniq;

template<int First, int... Last>
struct uniq<Vector<First, First, Last...>> {
    using type = typename uniq<Vector<First, Last...>>::type;
};

template<int First, int... Last>
struct uniq<Vector<First, Last...>> {
    using type = typename Append<First, 
        typename uniq<Vector<Last...>>::type>::type;
};

template<int... I>
struct uniq<Vector<I...>> {
    using type = Vector<I...>;
};

关于c++ - 从编译时 vector 中删除相邻重复项的元程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63109411/

相关文章:

c++ - 不明确的调用 - 模板化函数

C++17 依赖名称不是类型,适用于 C++14

c++ - 在 C++ 中确定系统停止

c++ - 模板类方法的部分特化或实例化

ruby - 在 Ruby 中使用方法名称从字符串调用方法

c++ - 是否有可能在 C++ 中获取类型别名的名称?

c++ - 判断函数是否为const

c++ - 如何在 constexpr 函数中实现后备运行时实现

c++ - 为类中的字符串成员重载运算符>>时出错

c++ - 限制文件夹重命名 cocoa