我一直在尝试编写一个元函数来从定义为的编译时 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 但似乎无法弄清楚为什么没有任何效果。我是模板元编程的新手,在互联网上找不到很多示例。
如有任何帮助,我们将不胜感激。非常感谢。
最佳答案
您不需要模板模板参数
template<int...> class Vector
.当前两个元素相等时,应保留其中一个:
template <template<int...> class Vector, int First, int... Last> struct uniq<Vector<First, First, Last...>> { using type = typename uniq<Vector<First, Last...>>::type; // ^^^^^ };
你也应该处理空包。最简单的方法就是添加
...
: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/