可变长度初始值设定项的模板

Template for variable length initializer

本文关键字:      更新时间:2023-10-16

我需要一系列使用可变数量的值的初始值设定项函数。我正在使用它们来实现特征库的收集操作。这是我现在使用每个向量长度一个模板的方法:

template<typename T1, typename T2>
inline void gather (Array<T1,4,1> &to, const Array<T2,Dynamic,1> &from, const Array<int,4,1> &index) 
{
    to << from[index[0]], from[index[1]], from[index[2]], from[index[3]];
}
template<typename T1, typename T2>
inline void gather (Array<T1,6,1> &to, const Array<T2,Dynamic,1> &from, const Array<int,6,1> &index) 
{
    to << from[index[0]], from[index[1]], from[index[2]], from[index[3]], from[index[4]], from[index[5]];
}

有没有办法用长度参数参数化的单个模板替换上面更长的模板列表(上面代码段中的 4 和 6)?如果是这样,是否可以使用 C++11 之前的语言规范(我使用的是 Visual Studio 2010)?

我想保留逗号分隔值语法,因为我希望它在某些情况下会产生编译时初始化(const fromindex )。不过,我这个假设可能是错误的。初始值设定项列表可以有 1 到 16 个值 - 无需担心空列表。

不要在此设置中使用逗号初始值设定项语法,这会很麻烦。此语法用于在使用文本时提高可读性,但情况并非如此。

相反,我会推荐这样的东西:

template<typename T1, typename T2, unsigned int SIZE, unsigned int INDEX>
struct gather {
   gather(Array<T1,SIZE,1> &to, 
          const Array<T2,Dynamic,1> &from, 
          const Array<int,SIZE,1> &index) 
   {
      to.col(INDEX) = from[index[INDEX]];
      gather<T1,T2,SIZE,INDEX+1>(to,from, index);
   }
};
template<typename T1, typename T2, unsigned int SIZE>
struct gather<T1,T2,SIZE,SIZE>{
    gather(Array<T1,SIZE,1> &to, 
           const Array<T2,Dynamic,1> &from, 
           const Array<int,SIZE,1> &index)
    {
    }
};

这很好地产生了相同的效果,但静态(无循环)。

由于对函数的部分模板专用化限制,我在这里使用结构,但由于内联,它应该归结为相同。

基于重载 operator, 运算符来概括此语法非常棘手,结果充其量看起来很尴尬(如果它有效的话)。我建议尝试其他选项(例如,选择MatrixBase::operator<<(DenseBase&)运算符)。

如果你仍然想要它,你必须一个接一个地解压缩标量:

template<typename T1, typename T2, class CI, int Current, int Height>
inline void gather (Array<T1,Height,1> &to, const Array<T2,Dynamic,1> &from, const Array<int,Height,1> &index, CI&& ci, std::integral_constant<int, Current>*)
{
  gather(to, from, index, (ci,from[index[Current]]), (std::integral_constant<int, Current+1>*)0);
}
template<typename T1, typename T2, class CI, int Height>
inline void gather (Array<T1,Height,1> &to, const Array<T2,Dynamic,1> &from, const Array<int,Height,1> &index, CI&& ci, std::integral_constant<int, Height>*) {}
template<typename T1, typename T2, int Height>
inline void gather (Array<T1,Height,1> &to, const Array<T2,Dynamic,1> &from, const Array<int,Height,1> &index) {
  gather(to, from, index, (to << index[from[0]]), (std::integral_constant<int, 1>*)0);
}

丑陋,并且可能存在问题(您需要处理Dynamic值,如果可能的话,零高度,传递CommaInitializers递归等可能会出现问题)

此外,它具有线性模板实例化深度(恕我直言,在这种情况下这是不可避免的)。

相关文章:
  • 没有找到相关文章