C++ std::pair<T,T> 可变参数模板

C++ std::pair<T,T> variadic template

我遇到过这样的情况

template<typename T, unsigned int N, std::pair<T,T>... pairs>
struct Base{
    static constexpr std::pair<T,T> SOME_STATIC_ARRAY[N] = {pairs...};
};

struct Derived : Base<int,3,std::pair<int,int>(1,2),std::pair<int,int>(2,3),std::pair<int,int>(3,4)>{
    
};

我想要这样的东西,但是我得到编译错误

A non-type template parameter cannot have type 'std::pair<int, int>'

我怎样才能做到这一点?

非类型模板参数只能是 short list 对象类型之一:

  • 具有整数类型或枚举的值
  • 指向 class 对象的指针或引用
  • 指向函数的指针或引用
  • 指向class成员函数的指针或引用
  • std::nullptr_t

您临时构造的 std::pair 实例不在该列表中。模板参数非常挑剔。我不记得他们如此挑剔的确切原因,但考虑到模板专业化涉及询问“这些模板参数相同”。一般对象的相等性很棘手(通常涉及 operator==),因此将有效值集严格限制为具有琐碎的相等性概念的事物肯定会使编译器更简单。令我懊恼的是,你甚至不能使用 strings 作为非类型模板参数,无论它有多么惊人的有用!

您可以使用两种解决方案来解决此问题

  • 不是传递 N 对,而是传递 N*2 个单独的整数,因为整数是有效的非类型模板参数
  • 使用std::integral_constant传入整数,如std::pair<std::integral_constant<int, 1>, std::integral_constant<int, 2> >。这确实 not 生成了一对整数,但它确实生成了 type 模板参数而不是非类型模板参数。然后,您可以随时从模板函数中重建 std::pair<int, int>
    • 作为一个可能更简单的变体,您可以构建自己的 template <typename T, T First, T Second> struct pair_integral_constant class,它接受两个相同类型的数字。思路是一样的:让它成为类型参数而不是非类型参数。