通用功能模板返回一个大小的容器比输入容器的大小小

Generic function template that returns a container of size one less than size of input container

本文关键字:小小 输入 一个 功能 返回      更新时间:2023-10-16

我想实现一个函数,该函数将随机访问n> = 1个元素,并返回另一个N-1元素的随机访问容器。我希望该功能可以与STD :: Array,STD :: vector,STD :: Valarray一起使用,并为其他非标准随机访问容器提供扩展。如果可以与普通C阵列一起使用,那将是一个奖励,但不是必需的。

该应用是伯恩斯坦多项式衍生物,其中多项式系数存储在随机访问容器中(通常很小,即N< = 10(。这是一个外观的示例:

template <class InputContainer, class OutputContainer /* deduced from InputContainer? */>
OutputContainer compute_derivative(const InputContainer &c)
{
   // Create and return an OutputContainer by iterating over elements of c
}

此外,InputContainer::value_type可以是floatdoublestd::complex<float>std::complex<double>,甚至可能是std::arraystd::vector。这些元素代表伯恩斯坦多项式的系数,并确定多项式是标量函数,平面曲线(具有2个元素的系数(还是空间曲线(具有3个元素的系数(或更高阶的空间曲线。

>

是否有任何示例的人知道,对于我提到的容器并保留在容器中的类型的容器中,可以处理这种类型的应用程序?我想一次实现该算法,并适用于容器类型和系数类型的所有可能排列,但我意识到这可能是不可能的。

假定std::vector<double>的示例实现:

std::vector<double> compute_derivative_coefficients(const std::vector<double>& c) {
  const auto N = c.size();
  std::vector<double> c_d;  // empty
  if (N > 1) {              // 0 or 1 element vectors both return an empty vector
    c_d.reserve(N - 1)
    for (std::size_t k = 0; k < N - 1; ++k) {
      c_d[k] = (N - 1) * (c[k + 1] - c[k]);
    }
  }
  return c_d;
}

这里有几件事可以打开包装。

首先。推论输出容器类型并不像听起来那样微不足道,例如array<T,N>必须推导到类型array<T,(N-1)>,而vector<T>必须返回vector<T>(与输入类型相同(。因此,我相信您必须手动为与某些默认设置不同的所有容器类型指定扣除规则。例如:

template <typename Container>
struct Otp {
  typedef Container Type;
};
template <typename T, ::std::size_t N>
struct Otp<::std::array<T,N>> {
  typedef ::std::array<T,(N-1)> Type;
};

等等。(免责声明是为了表明这个想法,我没有运行这个想法,也没有声称考虑所有可能的要求。(

第二,函数的实际实现。如果您希望它与任何容器类型一起使用,则应以某些形式或其他形式使用迭代器对。特别是::std::begin(c)::std::end(c),因为成员功能在不同类型的情况下变化,而C风格数组没有任何。

问题现在是构建vector<T>array<T,(N-1)>是两个根本不同的事物,因为数组立即初始化其成员,并且在矢量以尺寸0开始时具有尺寸N-1(和容量0(。

因此,它可以理解您要用其中的内容直接初始化容器。

您需要Sort OutputContainer oc = {begin,end-1};的初始化函数。不幸的是,据我所知,列表定位类型(例如T[]array(都不存在此类操作。


因此,我想您最好的选择是区分需要列出初始化的类型,并希望所有这些类型都是默认的构造构造,并且立即具有最终尺寸。然后,您可以实现两个版本的通用功能。一个只是默认的一个初始化返回值容器,然后用内容填充它。也许您可以在其endbegin迭代器之间的距离上使用if constexpr。第二个版本是用于了解迭代仪对的类型,例如vector

总的来说,这可能不是微不足道的,并且有很多陷阱。我希望人们可以在适当地实现这样的一般功能的同时学到很多有关容器的知识,但是我可以肯定的是,仅对您期望它使用的少数类型实施它会容易得多。